1 //===- IntegerRelation.cpp - MLIR IntegerRelation Class ---------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // A class to represent an relation over integer tuples. A relation is
10 // represented as a constraint system over a space of tuples of integer valued
11 // varaiables supporting symbolic identifiers and existential quantification.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "mlir/Analysis/Presburger/IntegerRelation.h"
16 #include "mlir/Analysis/Presburger/LinearTransform.h"
17 #include "mlir/Analysis/Presburger/PresburgerRelation.h"
18 #include "mlir/Analysis/Presburger/Simplex.h"
19 #include "mlir/Analysis/Presburger/Utils.h"
20 #include "llvm/ADT/DenseMap.h"
21 #include "llvm/ADT/DenseSet.h"
22 #include "llvm/Support/Debug.h"
23 
24 #define DEBUG_TYPE "presburger"
25 
26 using namespace mlir;
27 using namespace presburger;
28 
29 using llvm::SmallDenseMap;
30 using llvm::SmallDenseSet;
31 
32 std::unique_ptr<IntegerRelation> IntegerRelation::clone() const {
33   return std::make_unique<IntegerRelation>(*this);
34 }
35 
36 std::unique_ptr<IntegerPolyhedron> IntegerPolyhedron::clone() const {
37   return std::make_unique<IntegerPolyhedron>(*this);
38 }
39 
40 void IntegerRelation::append(const IntegerRelation &other) {
41   assert(PresburgerLocalSpace::isEqual(other) && "Spaces must be equal.");
42 
43   inequalities.reserveRows(inequalities.getNumRows() +
44                            other.getNumInequalities());
45   equalities.reserveRows(equalities.getNumRows() + other.getNumEqualities());
46 
47   for (unsigned r = 0, e = other.getNumInequalities(); r < e; r++) {
48     addInequality(other.getInequality(r));
49   }
50   for (unsigned r = 0, e = other.getNumEqualities(); r < e; r++) {
51     addEquality(other.getEquality(r));
52   }
53 }
54 
55 IntegerRelation IntegerRelation::intersect(IntegerRelation other) const {
56   IntegerRelation result = *this;
57   result.mergeLocalIds(other);
58   result.append(other);
59   return result;
60 }
61 
62 bool IntegerRelation::isEqual(const IntegerRelation &other) const {
63   assert(PresburgerLocalSpace::isEqual(other) && "Spaces must be equal.");
64   return PresburgerRelation(*this).isEqual(PresburgerRelation(other));
65 }
66 
67 bool IntegerRelation::isSubsetOf(const IntegerRelation &other) const {
68   assert(PresburgerLocalSpace::isEqual(other) && "Spaces must be equal.");
69   return PresburgerRelation(*this).isSubsetOf(PresburgerRelation(other));
70 }
71 
72 MaybeOptimum<SmallVector<Fraction, 8>>
73 IntegerRelation::findRationalLexMin() const {
74   assert(getNumSymbolIds() == 0 && "Symbols are not supported!");
75   MaybeOptimum<SmallVector<Fraction, 8>> maybeLexMin =
76       LexSimplex(*this).findRationalLexMin();
77 
78   if (!maybeLexMin.isBounded())
79     return maybeLexMin;
80 
81   // The Simplex returns the lexmin over all the variables including locals. But
82   // locals are not actually part of the space and should not be returned in the
83   // result. Since the locals are placed last in the list of identifiers, they
84   // will be minimized last in the lexmin. So simply truncating out the locals
85   // from the end of the answer gives the desired lexmin over the dimensions.
86   assert(maybeLexMin->size() == getNumIds() &&
87          "Incorrect number of vars in lexMin!");
88   maybeLexMin->resize(getNumDimAndSymbolIds());
89   return maybeLexMin;
90 }
91 
92 MaybeOptimum<SmallVector<int64_t, 8>>
93 IntegerRelation::findIntegerLexMin() const {
94   assert(getNumSymbolIds() == 0 && "Symbols are not supported!");
95   MaybeOptimum<SmallVector<int64_t, 8>> maybeLexMin =
96       LexSimplex(*this).findIntegerLexMin();
97 
98   if (!maybeLexMin.isBounded())
99     return maybeLexMin.getKind();
100 
101   // The Simplex returns the lexmin over all the variables including locals. But
102   // locals are not actually part of the space and should not be returned in the
103   // result. Since the locals are placed last in the list of identifiers, they
104   // will be minimized last in the lexmin. So simply truncating out the locals
105   // from the end of the answer gives the desired lexmin over the dimensions.
106   assert(maybeLexMin->size() == getNumIds() &&
107          "Incorrect number of vars in lexMin!");
108   maybeLexMin->resize(getNumDimAndSymbolIds());
109   return maybeLexMin;
110 }
111 
112 static bool rangeIsZero(ArrayRef<int64_t> range) {
113   return llvm::all_of(range, [](int64_t x) { return x == 0; });
114 }
115 
116 void removeConstraintsInvolvingIdRange(IntegerRelation &poly, unsigned begin,
117                                        unsigned count) {
118   // We loop until i > 0 and index into i - 1 to avoid sign issues.
119   //
120   // We iterate backwards so that whether we remove constraint i - 1 or not, the
121   // next constraint to be tested is always i - 2.
122   for (unsigned i = poly.getNumEqualities(); i > 0; i--)
123     if (!rangeIsZero(poly.getEquality(i - 1).slice(begin, count)))
124       poly.removeEquality(i - 1);
125   for (unsigned i = poly.getNumInequalities(); i > 0; i--)
126     if (!rangeIsZero(poly.getInequality(i - 1).slice(begin, count)))
127       poly.removeInequality(i - 1);
128 }
129 unsigned IntegerRelation::insertId(IdKind kind, unsigned pos, unsigned num) {
130   assert(pos <= getNumIdKind(kind));
131 
132   unsigned insertPos = PresburgerLocalSpace::insertId(kind, pos, num);
133   inequalities.insertColumns(insertPos, num);
134   equalities.insertColumns(insertPos, num);
135   return insertPos;
136 }
137 
138 unsigned IntegerRelation::appendId(IdKind kind, unsigned num) {
139   unsigned pos = getNumIdKind(kind);
140   return insertId(kind, pos, num);
141 }
142 
143 void IntegerRelation::addEquality(ArrayRef<int64_t> eq) {
144   assert(eq.size() == getNumCols());
145   unsigned row = equalities.appendExtraRow();
146   for (unsigned i = 0, e = eq.size(); i < e; ++i)
147     equalities(row, i) = eq[i];
148 }
149 
150 void IntegerRelation::addInequality(ArrayRef<int64_t> inEq) {
151   assert(inEq.size() == getNumCols());
152   unsigned row = inequalities.appendExtraRow();
153   for (unsigned i = 0, e = inEq.size(); i < e; ++i)
154     inequalities(row, i) = inEq[i];
155 }
156 
157 void IntegerRelation::removeId(IdKind kind, unsigned pos) {
158   removeIdRange(kind, pos, pos + 1);
159 }
160 
161 void IntegerRelation::removeId(unsigned pos) { removeIdRange(pos, pos + 1); }
162 
163 void IntegerRelation::removeIdRange(IdKind kind, unsigned idStart,
164                                     unsigned idLimit) {
165   assert(idLimit <= getNumIdKind(kind));
166 
167   if (idStart >= idLimit)
168     return;
169 
170   // Remove eliminated identifiers from the constraints.
171   unsigned offset = getIdKindOffset(kind);
172   equalities.removeColumns(offset + idStart, idLimit - idStart);
173   inequalities.removeColumns(offset + idStart, idLimit - idStart);
174 
175   // Remove eliminated identifiers from the space.
176   PresburgerLocalSpace::removeIdRange(kind, idStart, idLimit);
177 }
178 
179 void IntegerRelation::removeIdRange(unsigned idStart, unsigned idLimit) {
180   assert(idLimit <= getNumIds());
181 
182   if (idStart >= idLimit)
183     return;
184 
185   // Helper function to remove ids of the specified kind in the given range
186   // [start, limit), The range is absolute (i.e. it is not relative to the kind
187   // of identifier). Also updates `limit` to reflect the deleted identifiers.
188   auto removeIdKindInRange = [this](IdKind kind, unsigned &start,
189                                     unsigned &limit) {
190     if (start >= limit)
191       return;
192 
193     unsigned offset = getIdKindOffset(kind);
194     unsigned num = getNumIdKind(kind);
195 
196     // Get `start`, `limit` relative to the specified kind.
197     unsigned relativeStart =
198         start <= offset ? 0 : std::min(num, start - offset);
199     unsigned relativeLimit =
200         limit <= offset ? 0 : std::min(num, limit - offset);
201 
202     // Remove ids of the specified kind in the relative range.
203     removeIdRange(kind, relativeStart, relativeLimit);
204 
205     // Update `limit` to reflect deleted identifiers.
206     // `start` does not need to be updated because any identifiers that are
207     // deleted are after position `start`.
208     limit -= relativeLimit - relativeStart;
209   };
210 
211   removeIdKindInRange(IdKind::Domain, idStart, idLimit);
212   removeIdKindInRange(IdKind::Range, idStart, idLimit);
213   removeIdKindInRange(IdKind::Symbol, idStart, idLimit);
214   removeIdKindInRange(IdKind::Local, idStart, idLimit);
215 }
216 
217 void IntegerRelation::removeEquality(unsigned pos) {
218   equalities.removeRow(pos);
219 }
220 
221 void IntegerRelation::removeInequality(unsigned pos) {
222   inequalities.removeRow(pos);
223 }
224 
225 void IntegerRelation::removeEqualityRange(unsigned start, unsigned end) {
226   if (start >= end)
227     return;
228   equalities.removeRows(start, end - start);
229 }
230 
231 void IntegerRelation::removeInequalityRange(unsigned start, unsigned end) {
232   if (start >= end)
233     return;
234   inequalities.removeRows(start, end - start);
235 }
236 
237 void IntegerRelation::swapId(unsigned posA, unsigned posB) {
238   assert(posA < getNumIds() && "invalid position A");
239   assert(posB < getNumIds() && "invalid position B");
240 
241   if (posA == posB)
242     return;
243 
244   inequalities.swapColumns(posA, posB);
245   equalities.swapColumns(posA, posB);
246 }
247 
248 void IntegerRelation::clearConstraints() {
249   equalities.resizeVertically(0);
250   inequalities.resizeVertically(0);
251 }
252 
253 /// Gather all lower and upper bounds of the identifier at `pos`, and
254 /// optionally any equalities on it. In addition, the bounds are to be
255 /// independent of identifiers in position range [`offset`, `offset` + `num`).
256 void IntegerRelation::getLowerAndUpperBoundIndices(
257     unsigned pos, SmallVectorImpl<unsigned> *lbIndices,
258     SmallVectorImpl<unsigned> *ubIndices, SmallVectorImpl<unsigned> *eqIndices,
259     unsigned offset, unsigned num) const {
260   assert(pos < getNumIds() && "invalid position");
261   assert(offset + num < getNumCols() && "invalid range");
262 
263   // Checks for a constraint that has a non-zero coeff for the identifiers in
264   // the position range [offset, offset + num) while ignoring `pos`.
265   auto containsConstraintDependentOnRange = [&](unsigned r, bool isEq) {
266     unsigned c, f;
267     auto cst = isEq ? getEquality(r) : getInequality(r);
268     for (c = offset, f = offset + num; c < f; ++c) {
269       if (c == pos)
270         continue;
271       if (cst[c] != 0)
272         break;
273     }
274     return c < f;
275   };
276 
277   // Gather all lower bounds and upper bounds of the variable. Since the
278   // canonical form c_1*x_1 + c_2*x_2 + ... + c_0 >= 0, a constraint is a lower
279   // bound for x_i if c_i >= 1, and an upper bound if c_i <= -1.
280   for (unsigned r = 0, e = getNumInequalities(); r < e; r++) {
281     // The bounds are to be independent of [offset, offset + num) columns.
282     if (containsConstraintDependentOnRange(r, /*isEq=*/false))
283       continue;
284     if (atIneq(r, pos) >= 1) {
285       // Lower bound.
286       lbIndices->push_back(r);
287     } else if (atIneq(r, pos) <= -1) {
288       // Upper bound.
289       ubIndices->push_back(r);
290     }
291   }
292 
293   // An equality is both a lower and upper bound. Record any equalities
294   // involving the pos^th identifier.
295   if (!eqIndices)
296     return;
297 
298   for (unsigned r = 0, e = getNumEqualities(); r < e; r++) {
299     if (atEq(r, pos) == 0)
300       continue;
301     if (containsConstraintDependentOnRange(r, /*isEq=*/true))
302       continue;
303     eqIndices->push_back(r);
304   }
305 }
306 
307 bool IntegerRelation::hasConsistentState() const {
308   if (!inequalities.hasConsistentState())
309     return false;
310   if (!equalities.hasConsistentState())
311     return false;
312   return true;
313 }
314 
315 void IntegerRelation::setAndEliminate(unsigned pos, ArrayRef<int64_t> values) {
316   if (values.empty())
317     return;
318   assert(pos + values.size() <= getNumIds() &&
319          "invalid position or too many values");
320   // Setting x_j = p in sum_i a_i x_i + c is equivalent to adding p*a_j to the
321   // constant term and removing the id x_j. We do this for all the ids
322   // pos, pos + 1, ... pos + values.size() - 1.
323   unsigned constantColPos = getNumCols() - 1;
324   for (unsigned i = 0, numVals = values.size(); i < numVals; ++i)
325     inequalities.addToColumn(i + pos, constantColPos, values[i]);
326   for (unsigned i = 0, numVals = values.size(); i < numVals; ++i)
327     equalities.addToColumn(i + pos, constantColPos, values[i]);
328   removeIdRange(pos, pos + values.size());
329 }
330 
331 void IntegerRelation::clearAndCopyFrom(const IntegerRelation &other) {
332   *this = other;
333 }
334 
335 // Searches for a constraint with a non-zero coefficient at `colIdx` in
336 // equality (isEq=true) or inequality (isEq=false) constraints.
337 // Returns true and sets row found in search in `rowIdx`, false otherwise.
338 bool IntegerRelation::findConstraintWithNonZeroAt(unsigned colIdx, bool isEq,
339                                                   unsigned *rowIdx) const {
340   assert(colIdx < getNumCols() && "position out of bounds");
341   auto at = [&](unsigned rowIdx) -> int64_t {
342     return isEq ? atEq(rowIdx, colIdx) : atIneq(rowIdx, colIdx);
343   };
344   unsigned e = isEq ? getNumEqualities() : getNumInequalities();
345   for (*rowIdx = 0; *rowIdx < e; ++(*rowIdx)) {
346     if (at(*rowIdx) != 0) {
347       return true;
348     }
349   }
350   return false;
351 }
352 
353 void IntegerRelation::normalizeConstraintsByGCD() {
354   for (unsigned i = 0, e = getNumEqualities(); i < e; ++i)
355     equalities.normalizeRow(i);
356   for (unsigned i = 0, e = getNumInequalities(); i < e; ++i)
357     inequalities.normalizeRow(i);
358 }
359 
360 bool IntegerRelation::hasInvalidConstraint() const {
361   assert(hasConsistentState());
362   auto check = [&](bool isEq) -> bool {
363     unsigned numCols = getNumCols();
364     unsigned numRows = isEq ? getNumEqualities() : getNumInequalities();
365     for (unsigned i = 0, e = numRows; i < e; ++i) {
366       unsigned j;
367       for (j = 0; j < numCols - 1; ++j) {
368         int64_t v = isEq ? atEq(i, j) : atIneq(i, j);
369         // Skip rows with non-zero variable coefficients.
370         if (v != 0)
371           break;
372       }
373       if (j < numCols - 1) {
374         continue;
375       }
376       // Check validity of constant term at 'numCols - 1' w.r.t 'isEq'.
377       // Example invalid constraints include: '1 == 0' or '-1 >= 0'
378       int64_t v = isEq ? atEq(i, numCols - 1) : atIneq(i, numCols - 1);
379       if ((isEq && v != 0) || (!isEq && v < 0)) {
380         return true;
381       }
382     }
383     return false;
384   };
385   if (check(/*isEq=*/true))
386     return true;
387   return check(/*isEq=*/false);
388 }
389 
390 /// Eliminate identifier from constraint at `rowIdx` based on coefficient at
391 /// pivotRow, pivotCol. Columns in range [elimColStart, pivotCol) will not be
392 /// updated as they have already been eliminated.
393 static void eliminateFromConstraint(IntegerRelation *constraints,
394                                     unsigned rowIdx, unsigned pivotRow,
395                                     unsigned pivotCol, unsigned elimColStart,
396                                     bool isEq) {
397   // Skip if equality 'rowIdx' if same as 'pivotRow'.
398   if (isEq && rowIdx == pivotRow)
399     return;
400   auto at = [&](unsigned i, unsigned j) -> int64_t {
401     return isEq ? constraints->atEq(i, j) : constraints->atIneq(i, j);
402   };
403   int64_t leadCoeff = at(rowIdx, pivotCol);
404   // Skip if leading coefficient at 'rowIdx' is already zero.
405   if (leadCoeff == 0)
406     return;
407   int64_t pivotCoeff = constraints->atEq(pivotRow, pivotCol);
408   int64_t sign = (leadCoeff * pivotCoeff > 0) ? -1 : 1;
409   int64_t lcm = mlir::lcm(pivotCoeff, leadCoeff);
410   int64_t pivotMultiplier = sign * (lcm / std::abs(pivotCoeff));
411   int64_t rowMultiplier = lcm / std::abs(leadCoeff);
412 
413   unsigned numCols = constraints->getNumCols();
414   for (unsigned j = 0; j < numCols; ++j) {
415     // Skip updating column 'j' if it was just eliminated.
416     if (j >= elimColStart && j < pivotCol)
417       continue;
418     int64_t v = pivotMultiplier * constraints->atEq(pivotRow, j) +
419                 rowMultiplier * at(rowIdx, j);
420     isEq ? constraints->atEq(rowIdx, j) = v
421          : constraints->atIneq(rowIdx, j) = v;
422   }
423 }
424 
425 /// Returns the position of the identifier that has the minimum <number of lower
426 /// bounds> times <number of upper bounds> from the specified range of
427 /// identifiers [start, end). It is often best to eliminate in the increasing
428 /// order of these counts when doing Fourier-Motzkin elimination since FM adds
429 /// that many new constraints.
430 static unsigned getBestIdToEliminate(const IntegerRelation &cst, unsigned start,
431                                      unsigned end) {
432   assert(start < cst.getNumIds() && end < cst.getNumIds() + 1);
433 
434   auto getProductOfNumLowerUpperBounds = [&](unsigned pos) {
435     unsigned numLb = 0;
436     unsigned numUb = 0;
437     for (unsigned r = 0, e = cst.getNumInequalities(); r < e; r++) {
438       if (cst.atIneq(r, pos) > 0) {
439         ++numLb;
440       } else if (cst.atIneq(r, pos) < 0) {
441         ++numUb;
442       }
443     }
444     return numLb * numUb;
445   };
446 
447   unsigned minLoc = start;
448   unsigned min = getProductOfNumLowerUpperBounds(start);
449   for (unsigned c = start + 1; c < end; c++) {
450     unsigned numLbUbProduct = getProductOfNumLowerUpperBounds(c);
451     if (numLbUbProduct < min) {
452       min = numLbUbProduct;
453       minLoc = c;
454     }
455   }
456   return minLoc;
457 }
458 
459 // Checks for emptiness of the set by eliminating identifiers successively and
460 // using the GCD test (on all equality constraints) and checking for trivially
461 // invalid constraints. Returns 'true' if the constraint system is found to be
462 // empty; false otherwise.
463 bool IntegerRelation::isEmpty() const {
464   if (isEmptyByGCDTest() || hasInvalidConstraint())
465     return true;
466 
467   IntegerRelation tmpCst(*this);
468 
469   // First, eliminate as many local variables as possible using equalities.
470   tmpCst.removeRedundantLocalVars();
471   if (tmpCst.isEmptyByGCDTest() || tmpCst.hasInvalidConstraint())
472     return true;
473 
474   // Eliminate as many identifiers as possible using Gaussian elimination.
475   unsigned currentPos = 0;
476   while (currentPos < tmpCst.getNumIds()) {
477     tmpCst.gaussianEliminateIds(currentPos, tmpCst.getNumIds());
478     ++currentPos;
479     // We check emptiness through trivial checks after eliminating each ID to
480     // detect emptiness early. Since the checks isEmptyByGCDTest() and
481     // hasInvalidConstraint() are linear time and single sweep on the constraint
482     // buffer, this appears reasonable - but can optimize in the future.
483     if (tmpCst.hasInvalidConstraint() || tmpCst.isEmptyByGCDTest())
484       return true;
485   }
486 
487   // Eliminate the remaining using FM.
488   for (unsigned i = 0, e = tmpCst.getNumIds(); i < e; i++) {
489     tmpCst.fourierMotzkinEliminate(
490         getBestIdToEliminate(tmpCst, 0, tmpCst.getNumIds()));
491     // Check for a constraint explosion. This rarely happens in practice, but
492     // this check exists as a safeguard against improperly constructed
493     // constraint systems or artificially created arbitrarily complex systems
494     // that aren't the intended use case for IntegerRelation. This is
495     // needed since FM has a worst case exponential complexity in theory.
496     if (tmpCst.getNumConstraints() >= kExplosionFactor * getNumIds()) {
497       LLVM_DEBUG(llvm::dbgs() << "FM constraint explosion detected\n");
498       return false;
499     }
500 
501     // FM wouldn't have modified the equalities in any way. So no need to again
502     // run GCD test. Check for trivial invalid constraints.
503     if (tmpCst.hasInvalidConstraint())
504       return true;
505   }
506   return false;
507 }
508 
509 // Runs the GCD test on all equality constraints. Returns 'true' if this test
510 // fails on any equality. Returns 'false' otherwise.
511 // This test can be used to disprove the existence of a solution. If it returns
512 // true, no integer solution to the equality constraints can exist.
513 //
514 // GCD test definition:
515 //
516 // The equality constraint:
517 //
518 //  c_1*x_1 + c_2*x_2 + ... + c_n*x_n = c_0
519 //
520 // has an integer solution iff:
521 //
522 //  GCD of c_1, c_2, ..., c_n divides c_0.
523 //
524 bool IntegerRelation::isEmptyByGCDTest() const {
525   assert(hasConsistentState());
526   unsigned numCols = getNumCols();
527   for (unsigned i = 0, e = getNumEqualities(); i < e; ++i) {
528     uint64_t gcd = std::abs(atEq(i, 0));
529     for (unsigned j = 1; j < numCols - 1; ++j) {
530       gcd = llvm::GreatestCommonDivisor64(gcd, std::abs(atEq(i, j)));
531     }
532     int64_t v = std::abs(atEq(i, numCols - 1));
533     if (gcd > 0 && (v % gcd != 0)) {
534       return true;
535     }
536   }
537   return false;
538 }
539 
540 // Returns a matrix where each row is a vector along which the polytope is
541 // bounded. The span of the returned vectors is guaranteed to contain all
542 // such vectors. The returned vectors are NOT guaranteed to be linearly
543 // independent. This function should not be called on empty sets.
544 //
545 // It is sufficient to check the perpendiculars of the constraints, as the set
546 // of perpendiculars which are bounded must span all bounded directions.
547 Matrix IntegerRelation::getBoundedDirections() const {
548   // Note that it is necessary to add the equalities too (which the constructor
549   // does) even though we don't need to check if they are bounded; whether an
550   // inequality is bounded or not depends on what other constraints, including
551   // equalities, are present.
552   Simplex simplex(*this);
553 
554   assert(!simplex.isEmpty() && "It is not meaningful to ask whether a "
555                                "direction is bounded in an empty set.");
556 
557   SmallVector<unsigned, 8> boundedIneqs;
558   // The constructor adds the inequalities to the simplex first, so this
559   // processes all the inequalities.
560   for (unsigned i = 0, e = getNumInequalities(); i < e; ++i) {
561     if (simplex.isBoundedAlongConstraint(i))
562       boundedIneqs.push_back(i);
563   }
564 
565   // The direction vector is given by the coefficients and does not include the
566   // constant term, so the matrix has one fewer column.
567   unsigned dirsNumCols = getNumCols() - 1;
568   Matrix dirs(boundedIneqs.size() + getNumEqualities(), dirsNumCols);
569 
570   // Copy the bounded inequalities.
571   unsigned row = 0;
572   for (unsigned i : boundedIneqs) {
573     for (unsigned col = 0; col < dirsNumCols; ++col)
574       dirs(row, col) = atIneq(i, col);
575     ++row;
576   }
577 
578   // Copy the equalities. All the equalities' perpendiculars are bounded.
579   for (unsigned i = 0, e = getNumEqualities(); i < e; ++i) {
580     for (unsigned col = 0; col < dirsNumCols; ++col)
581       dirs(row, col) = atEq(i, col);
582     ++row;
583   }
584 
585   return dirs;
586 }
587 
588 bool IntegerRelation::isIntegerEmpty() const {
589   return !findIntegerSample().hasValue();
590 }
591 
592 /// Let this set be S. If S is bounded then we directly call into the GBR
593 /// sampling algorithm. Otherwise, there are some unbounded directions, i.e.,
594 /// vectors v such that S extends to infinity along v or -v. In this case we
595 /// use an algorithm described in the integer set library (isl) manual and used
596 /// by the isl_set_sample function in that library. The algorithm is:
597 ///
598 /// 1) Apply a unimodular transform T to S to obtain S*T, such that all
599 /// dimensions in which S*T is bounded lie in the linear span of a prefix of the
600 /// dimensions.
601 ///
602 /// 2) Construct a set B by removing all constraints that involve
603 /// the unbounded dimensions and then deleting the unbounded dimensions. Note
604 /// that B is a Bounded set.
605 ///
606 /// 3) Try to obtain a sample from B using the GBR sampling
607 /// algorithm. If no sample is found, return that S is empty.
608 ///
609 /// 4) Otherwise, substitute the obtained sample into S*T to obtain a set
610 /// C. C is a full-dimensional Cone and always contains a sample.
611 ///
612 /// 5) Obtain an integer sample from C.
613 ///
614 /// 6) Return T*v, where v is the concatenation of the samples from B and C.
615 ///
616 /// The following is a sketch of a proof that
617 /// a) If the algorithm returns empty, then S is empty.
618 /// b) If the algorithm returns a sample, it is a valid sample in S.
619 ///
620 /// The algorithm returns empty only if B is empty, in which case S*T is
621 /// certainly empty since B was obtained by removing constraints and then
622 /// deleting unconstrained dimensions from S*T. Since T is unimodular, a vector
623 /// v is in S*T iff T*v is in S. So in this case, since
624 /// S*T is empty, S is empty too.
625 ///
626 /// Otherwise, the algorithm substitutes the sample from B into S*T. All the
627 /// constraints of S*T that did not involve unbounded dimensions are satisfied
628 /// by this substitution. All dimensions in the linear span of the dimensions
629 /// outside the prefix are unbounded in S*T (step 1). Substituting values for
630 /// the bounded dimensions cannot make these dimensions bounded, and these are
631 /// the only remaining dimensions in C, so C is unbounded along every vector (in
632 /// the positive or negative direction, or both). C is hence a full-dimensional
633 /// cone and therefore always contains an integer point.
634 ///
635 /// Concatenating the samples from B and C gives a sample v in S*T, so the
636 /// returned sample T*v is a sample in S.
637 Optional<SmallVector<int64_t, 8>> IntegerRelation::findIntegerSample() const {
638   // First, try the GCD test heuristic.
639   if (isEmptyByGCDTest())
640     return {};
641 
642   Simplex simplex(*this);
643   if (simplex.isEmpty())
644     return {};
645 
646   // For a bounded set, we directly call into the GBR sampling algorithm.
647   if (!simplex.isUnbounded())
648     return simplex.findIntegerSample();
649 
650   // The set is unbounded. We cannot directly use the GBR algorithm.
651   //
652   // m is a matrix containing, in each row, a vector in which S is
653   // bounded, such that the linear span of all these dimensions contains all
654   // bounded dimensions in S.
655   Matrix m = getBoundedDirections();
656   // In column echelon form, each row of m occupies only the first rank(m)
657   // columns and has zeros on the other columns. The transform T that brings S
658   // to column echelon form is unimodular as well, so this is a suitable
659   // transform to use in step 1 of the algorithm.
660   std::pair<unsigned, LinearTransform> result =
661       LinearTransform::makeTransformToColumnEchelon(std::move(m));
662   const LinearTransform &transform = result.second;
663   // 1) Apply T to S to obtain S*T.
664   IntegerRelation transformedSet = transform.applyTo(*this);
665 
666   // 2) Remove the unbounded dimensions and constraints involving them to
667   // obtain a bounded set.
668   IntegerRelation boundedSet(transformedSet);
669   unsigned numBoundedDims = result.first;
670   unsigned numUnboundedDims = getNumIds() - numBoundedDims;
671   removeConstraintsInvolvingIdRange(boundedSet, numBoundedDims,
672                                     numUnboundedDims);
673   boundedSet.removeIdRange(numBoundedDims, boundedSet.getNumIds());
674 
675   // 3) Try to obtain a sample from the bounded set.
676   Optional<SmallVector<int64_t, 8>> boundedSample =
677       Simplex(boundedSet).findIntegerSample();
678   if (!boundedSample)
679     return {};
680   assert(boundedSet.containsPoint(*boundedSample) &&
681          "Simplex returned an invalid sample!");
682 
683   // 4) Substitute the values of the bounded dimensions into S*T to obtain a
684   // full-dimensional cone, which necessarily contains an integer sample.
685   transformedSet.setAndEliminate(0, *boundedSample);
686   IntegerRelation &cone = transformedSet;
687 
688   // 5) Obtain an integer sample from the cone.
689   //
690   // We shrink the cone such that for any rational point in the shrunken cone,
691   // rounding up each of the point's coordinates produces a point that still
692   // lies in the original cone.
693   //
694   // Rounding up a point x adds a number e_i in [0, 1) to each coordinate x_i.
695   // For each inequality sum_i a_i x_i + c >= 0 in the original cone, the
696   // shrunken cone will have the inequality tightened by some amount s, such
697   // that if x satisfies the shrunken cone's tightened inequality, then x + e
698   // satisfies the original inequality, i.e.,
699   //
700   // sum_i a_i x_i + c + s >= 0 implies sum_i a_i (x_i + e_i) + c >= 0
701   //
702   // for any e_i values in [0, 1). In fact, we will handle the slightly more
703   // general case where e_i can be in [0, 1]. For example, consider the
704   // inequality 2x_1 - 3x_2 - 7x_3 - 6 >= 0, and let x = (3, 0, 0). How low
705   // could the LHS go if we added a number in [0, 1] to each coordinate? The LHS
706   // is minimized when we add 1 to the x_i with negative coefficient a_i and
707   // keep the other x_i the same. In the example, we would get x = (3, 1, 1),
708   // changing the value of the LHS by -3 + -7 = -10.
709   //
710   // In general, the value of the LHS can change by at most the sum of the
711   // negative a_i, so we accomodate this by shifting the inequality by this
712   // amount for the shrunken cone.
713   for (unsigned i = 0, e = cone.getNumInequalities(); i < e; ++i) {
714     for (unsigned j = 0; j < cone.getNumIds(); ++j) {
715       int64_t coeff = cone.atIneq(i, j);
716       if (coeff < 0)
717         cone.atIneq(i, cone.getNumIds()) += coeff;
718     }
719   }
720 
721   // Obtain an integer sample in the cone by rounding up a rational point from
722   // the shrunken cone. Shrinking the cone amounts to shifting its apex
723   // "inwards" without changing its "shape"; the shrunken cone is still a
724   // full-dimensional cone and is hence non-empty.
725   Simplex shrunkenConeSimplex(cone);
726   assert(!shrunkenConeSimplex.isEmpty() && "Shrunken cone cannot be empty!");
727 
728   // The sample will always exist since the shrunken cone is non-empty.
729   SmallVector<Fraction, 8> shrunkenConeSample =
730       *shrunkenConeSimplex.getRationalSample();
731 
732   SmallVector<int64_t, 8> coneSample(llvm::map_range(shrunkenConeSample, ceil));
733 
734   // 6) Return transform * concat(boundedSample, coneSample).
735   SmallVector<int64_t, 8> &sample = boundedSample.getValue();
736   sample.append(coneSample.begin(), coneSample.end());
737   return transform.postMultiplyWithColumn(sample);
738 }
739 
740 /// Helper to evaluate an affine expression at a point.
741 /// The expression is a list of coefficients for the dimensions followed by the
742 /// constant term.
743 static int64_t valueAt(ArrayRef<int64_t> expr, ArrayRef<int64_t> point) {
744   assert(expr.size() == 1 + point.size() &&
745          "Dimensionalities of point and expression don't match!");
746   int64_t value = expr.back();
747   for (unsigned i = 0; i < point.size(); ++i)
748     value += expr[i] * point[i];
749   return value;
750 }
751 
752 /// A point satisfies an equality iff the value of the equality at the
753 /// expression is zero, and it satisfies an inequality iff the value of the
754 /// inequality at that point is non-negative.
755 bool IntegerRelation::containsPoint(ArrayRef<int64_t> point) const {
756   for (unsigned i = 0, e = getNumEqualities(); i < e; ++i) {
757     if (valueAt(getEquality(i), point) != 0)
758       return false;
759   }
760   for (unsigned i = 0, e = getNumInequalities(); i < e; ++i) {
761     if (valueAt(getInequality(i), point) < 0)
762       return false;
763   }
764   return true;
765 }
766 
767 void IntegerRelation::getLocalReprs(std::vector<MaybeLocalRepr> &repr) const {
768   std::vector<SmallVector<int64_t, 8>> dividends(getNumLocalIds());
769   SmallVector<unsigned, 4> denominators(getNumLocalIds());
770   getLocalReprs(dividends, denominators, repr);
771 }
772 
773 void IntegerRelation::getLocalReprs(
774     std::vector<SmallVector<int64_t, 8>> &dividends,
775     SmallVector<unsigned, 4> &denominators) const {
776   std::vector<MaybeLocalRepr> repr(getNumLocalIds());
777   getLocalReprs(dividends, denominators, repr);
778 }
779 
780 void IntegerRelation::getLocalReprs(
781     std::vector<SmallVector<int64_t, 8>> &dividends,
782     SmallVector<unsigned, 4> &denominators,
783     std::vector<MaybeLocalRepr> &repr) const {
784 
785   repr.resize(getNumLocalIds());
786   dividends.resize(getNumLocalIds());
787   denominators.resize(getNumLocalIds());
788 
789   SmallVector<bool, 8> foundRepr(getNumIds(), false);
790   for (unsigned i = 0, e = getNumDimAndSymbolIds(); i < e; ++i)
791     foundRepr[i] = true;
792 
793   unsigned divOffset = getNumDimAndSymbolIds();
794   bool changed;
795   do {
796     // Each time changed is true, at end of this iteration, one or more local
797     // vars have been detected as floor divs.
798     changed = false;
799     for (unsigned i = 0, e = getNumLocalIds(); i < e; ++i) {
800       if (!foundRepr[i + divOffset]) {
801         MaybeLocalRepr res = computeSingleVarRepr(
802             *this, foundRepr, divOffset + i, dividends[i], denominators[i]);
803         if (!res)
804           continue;
805         foundRepr[i + divOffset] = true;
806         repr[i] = res;
807         changed = true;
808       }
809     }
810   } while (changed);
811 
812   // Set 0 denominator for identifiers for which no division representation
813   // could be found.
814   for (unsigned i = 0, e = repr.size(); i < e; ++i)
815     if (!repr[i])
816       denominators[i] = 0;
817 }
818 
819 /// Tightens inequalities given that we are dealing with integer spaces. This is
820 /// analogous to the GCD test but applied to inequalities. The constant term can
821 /// be reduced to the preceding multiple of the GCD of the coefficients, i.e.,
822 ///  64*i - 100 >= 0  =>  64*i - 128 >= 0 (since 'i' is an integer). This is a
823 /// fast method - linear in the number of coefficients.
824 // Example on how this affects practical cases: consider the scenario:
825 // 64*i >= 100, j = 64*i; without a tightening, elimination of i would yield
826 // j >= 100 instead of the tighter (exact) j >= 128.
827 void IntegerRelation::gcdTightenInequalities() {
828   unsigned numCols = getNumCols();
829   for (unsigned i = 0, e = getNumInequalities(); i < e; ++i) {
830     // Normalize the constraint and tighten the constant term by the GCD.
831     uint64_t gcd = inequalities.normalizeRow(i, getNumCols() - 1);
832     if (gcd > 1)
833       atIneq(i, numCols - 1) = mlir::floorDiv(atIneq(i, numCols - 1), gcd);
834   }
835 }
836 
837 // Eliminates all identifier variables in column range [posStart, posLimit).
838 // Returns the number of variables eliminated.
839 unsigned IntegerRelation::gaussianEliminateIds(unsigned posStart,
840                                                unsigned posLimit) {
841   // Return if identifier positions to eliminate are out of range.
842   assert(posLimit <= getNumIds());
843   assert(hasConsistentState());
844 
845   if (posStart >= posLimit)
846     return 0;
847 
848   gcdTightenInequalities();
849 
850   unsigned pivotCol = 0;
851   for (pivotCol = posStart; pivotCol < posLimit; ++pivotCol) {
852     // Find a row which has a non-zero coefficient in column 'j'.
853     unsigned pivotRow;
854     if (!findConstraintWithNonZeroAt(pivotCol, /*isEq=*/true, &pivotRow)) {
855       // No pivot row in equalities with non-zero at 'pivotCol'.
856       if (!findConstraintWithNonZeroAt(pivotCol, /*isEq=*/false, &pivotRow)) {
857         // If inequalities are also non-zero in 'pivotCol', it can be
858         // eliminated.
859         continue;
860       }
861       break;
862     }
863 
864     // Eliminate identifier at 'pivotCol' from each equality row.
865     for (unsigned i = 0, e = getNumEqualities(); i < e; ++i) {
866       eliminateFromConstraint(this, i, pivotRow, pivotCol, posStart,
867                               /*isEq=*/true);
868       equalities.normalizeRow(i);
869     }
870 
871     // Eliminate identifier at 'pivotCol' from each inequality row.
872     for (unsigned i = 0, e = getNumInequalities(); i < e; ++i) {
873       eliminateFromConstraint(this, i, pivotRow, pivotCol, posStart,
874                               /*isEq=*/false);
875       inequalities.normalizeRow(i);
876     }
877     removeEquality(pivotRow);
878     gcdTightenInequalities();
879   }
880   // Update position limit based on number eliminated.
881   posLimit = pivotCol;
882   // Remove eliminated columns from all constraints.
883   removeIdRange(posStart, posLimit);
884   return posLimit - posStart;
885 }
886 
887 // A more complex check to eliminate redundant inequalities. Uses FourierMotzkin
888 // to check if a constraint is redundant.
889 void IntegerRelation::removeRedundantInequalities() {
890   SmallVector<bool, 32> redun(getNumInequalities(), false);
891   // To check if an inequality is redundant, we replace the inequality by its
892   // complement (for eg., i - 1 >= 0 by i <= 0), and check if the resulting
893   // system is empty. If it is, the inequality is redundant.
894   IntegerRelation tmpCst(*this);
895   for (unsigned r = 0, e = getNumInequalities(); r < e; r++) {
896     // Change the inequality to its complement.
897     tmpCst.inequalities.negateRow(r);
898     tmpCst.atIneq(r, tmpCst.getNumCols() - 1)--;
899     if (tmpCst.isEmpty()) {
900       redun[r] = true;
901       // Zero fill the redundant inequality.
902       inequalities.fillRow(r, /*value=*/0);
903       tmpCst.inequalities.fillRow(r, /*value=*/0);
904     } else {
905       // Reverse the change (to avoid recreating tmpCst each time).
906       tmpCst.atIneq(r, tmpCst.getNumCols() - 1)++;
907       tmpCst.inequalities.negateRow(r);
908     }
909   }
910 
911   unsigned pos = 0;
912   for (unsigned r = 0, e = getNumInequalities(); r < e; ++r) {
913     if (!redun[r])
914       inequalities.copyRow(r, pos++);
915   }
916   inequalities.resizeVertically(pos);
917 }
918 
919 // A more complex check to eliminate redundant inequalities and equalities. Uses
920 // Simplex to check if a constraint is redundant.
921 void IntegerRelation::removeRedundantConstraints() {
922   // First, we run gcdTightenInequalities. This allows us to catch some
923   // constraints which are not redundant when considering rational solutions
924   // but are redundant in terms of integer solutions.
925   gcdTightenInequalities();
926   Simplex simplex(*this);
927   simplex.detectRedundant();
928 
929   unsigned pos = 0;
930   unsigned numIneqs = getNumInequalities();
931   // Scan to get rid of all inequalities marked redundant, in-place. In Simplex,
932   // the first constraints added are the inequalities.
933   for (unsigned r = 0; r < numIneqs; r++) {
934     if (!simplex.isMarkedRedundant(r))
935       inequalities.copyRow(r, pos++);
936   }
937   inequalities.resizeVertically(pos);
938 
939   // Scan to get rid of all equalities marked redundant, in-place. In Simplex,
940   // after the inequalities, a pair of constraints for each equality is added.
941   // An equality is redundant if both the inequalities in its pair are
942   // redundant.
943   pos = 0;
944   for (unsigned r = 0, e = getNumEqualities(); r < e; r++) {
945     if (!(simplex.isMarkedRedundant(numIneqs + 2 * r) &&
946           simplex.isMarkedRedundant(numIneqs + 2 * r + 1)))
947       equalities.copyRow(r, pos++);
948   }
949   equalities.resizeVertically(pos);
950 }
951 
952 Optional<uint64_t> IntegerRelation::computeVolume() const {
953   assert(getNumSymbolIds() == 0 && "Symbols are not yet supported!");
954 
955   Simplex simplex(*this);
956   // If the polytope is rationally empty, there are certainly no integer
957   // points.
958   if (simplex.isEmpty())
959     return 0;
960 
961   // Just find the maximum and minimum integer value of each non-local id
962   // separately, thus finding the number of integer values each such id can
963   // take. Multiplying these together gives a valid overapproximation of the
964   // number of integer points in the relation. The result this gives is
965   // equivalent to projecting (rationally) the relation onto its non-local ids
966   // and returning the number of integer points in a minimal axis-parallel
967   // hyperrectangular overapproximation of that.
968   //
969   // We also handle the special case where one dimension is unbounded and
970   // another dimension can take no integer values. In this case, the volume is
971   // zero.
972   //
973   // If there is no such empty dimension, if any dimension is unbounded we
974   // just return the result as unbounded.
975   uint64_t count = 1;
976   SmallVector<int64_t, 8> dim(getNumIds() + 1);
977   bool hasUnboundedId = false;
978   for (unsigned i = 0, e = getNumDimAndSymbolIds(); i < e; ++i) {
979     dim[i] = 1;
980     MaybeOptimum<int64_t> min, max;
981     std::tie(min, max) = simplex.computeIntegerBounds(dim);
982     dim[i] = 0;
983 
984     assert((!min.isEmpty() && !max.isEmpty()) &&
985            "Polytope should be rationally non-empty!");
986 
987     // One of the dimensions is unbounded. Note this fact. We will return
988     // unbounded if none of the other dimensions makes the volume zero.
989     if (min.isUnbounded() || max.isUnbounded()) {
990       hasUnboundedId = true;
991       continue;
992     }
993 
994     // In this case there are no valid integer points and the volume is
995     // definitely zero.
996     if (min.getBoundedOptimum() > max.getBoundedOptimum())
997       return 0;
998 
999     count *= (*max - *min + 1);
1000   }
1001 
1002   if (count == 0)
1003     return 0;
1004   if (hasUnboundedId)
1005     return {};
1006   return count;
1007 }
1008 
1009 void IntegerRelation::eliminateRedundantLocalId(unsigned posA, unsigned posB) {
1010   assert(posA < getNumLocalIds() && "Invalid local id position");
1011   assert(posB < getNumLocalIds() && "Invalid local id position");
1012 
1013   unsigned localOffset = getIdKindOffset(IdKind::Local);
1014   posA += localOffset;
1015   posB += localOffset;
1016   inequalities.addToColumn(posB, posA, 1);
1017   equalities.addToColumn(posB, posA, 1);
1018   removeId(posB);
1019 }
1020 
1021 /// Adds additional local ids to the sets such that they both have the union
1022 /// of the local ids in each set, without changing the set of points that
1023 /// lie in `this` and `other`.
1024 ///
1025 /// To detect local ids that always take the same in both sets, each local id is
1026 /// represented as a floordiv with constant denominator in terms of other ids.
1027 /// After extracting these divisions, local ids with the same division
1028 /// representation are considered duplicate and are merged. It is possible that
1029 /// division representation for some local id cannot be obtained, and thus these
1030 /// local ids are not considered for detecting duplicates.
1031 void IntegerRelation::mergeLocalIds(IntegerRelation &other) {
1032   assert(PresburgerSpace::isEqual(other) && "Spaces should match.");
1033 
1034   IntegerRelation &relA = *this;
1035   IntegerRelation &relB = other;
1036 
1037   // Merge local ids of relA and relB without using division information,
1038   // i.e. append local ids of `relB` to `relA` and insert local ids of `relA`
1039   // to `relB` at start of its local ids.
1040   unsigned initLocals = relA.getNumLocalIds();
1041   insertId(IdKind::Local, relA.getNumLocalIds(), relB.getNumLocalIds());
1042   relB.insertId(IdKind::Local, 0, initLocals);
1043 
1044   // Get division representations from each rel.
1045   std::vector<SmallVector<int64_t, 8>> divsA, divsB;
1046   SmallVector<unsigned, 4> denomsA, denomsB;
1047   relA.getLocalReprs(divsA, denomsA);
1048   relB.getLocalReprs(divsB, denomsB);
1049 
1050   // Copy division information for relB into `divsA` and `denomsA`, so that
1051   // these have the combined division information of both rels. Since newly
1052   // added local variables in relA and relB have no constraints, they will not
1053   // have any division representation.
1054   std::copy(divsB.begin() + initLocals, divsB.end(),
1055             divsA.begin() + initLocals);
1056   std::copy(denomsB.begin() + initLocals, denomsB.end(),
1057             denomsA.begin() + initLocals);
1058 
1059   // Merge function that merges the local variables in both sets by treating
1060   // them as the same identifier.
1061   auto merge = [&relA, &relB](unsigned i, unsigned j) -> bool {
1062     relA.eliminateRedundantLocalId(i, j);
1063     relB.eliminateRedundantLocalId(i, j);
1064     return true;
1065   };
1066 
1067   // Merge all divisions by removing duplicate divisions.
1068   unsigned localOffset = getIdKindOffset(IdKind::Local);
1069   removeDuplicateDivs(divsA, denomsA, localOffset, merge);
1070 }
1071 
1072 /// Removes local variables using equalities. Each equality is checked if it
1073 /// can be reduced to the form: `e = affine-expr`, where `e` is a local
1074 /// variable and `affine-expr` is an affine expression not containing `e`.
1075 /// If an equality satisfies this form, the local variable is replaced in
1076 /// each constraint and then removed. The equality used to replace this local
1077 /// variable is also removed.
1078 void IntegerRelation::removeRedundantLocalVars() {
1079   // Normalize the equality constraints to reduce coefficients of local
1080   // variables to 1 wherever possible.
1081   for (unsigned i = 0, e = getNumEqualities(); i < e; ++i)
1082     equalities.normalizeRow(i);
1083 
1084   while (true) {
1085     unsigned i, e, j, f;
1086     for (i = 0, e = getNumEqualities(); i < e; ++i) {
1087       // Find a local variable to eliminate using ith equality.
1088       for (j = getNumDimAndSymbolIds(), f = getNumIds(); j < f; ++j)
1089         if (std::abs(atEq(i, j)) == 1)
1090           break;
1091 
1092       // Local variable can be eliminated using ith equality.
1093       if (j < f)
1094         break;
1095     }
1096 
1097     // No equality can be used to eliminate a local variable.
1098     if (i == e)
1099       break;
1100 
1101     // Use the ith equality to simplify other equalities. If any changes
1102     // are made to an equality constraint, it is normalized by GCD.
1103     for (unsigned k = 0, t = getNumEqualities(); k < t; ++k) {
1104       if (atEq(k, j) != 0) {
1105         eliminateFromConstraint(this, k, i, j, j, /*isEq=*/true);
1106         equalities.normalizeRow(k);
1107       }
1108     }
1109 
1110     // Use the ith equality to simplify inequalities.
1111     for (unsigned k = 0, t = getNumInequalities(); k < t; ++k)
1112       eliminateFromConstraint(this, k, i, j, j, /*isEq=*/false);
1113 
1114     // Remove the ith equality and the found local variable.
1115     removeId(j);
1116     removeEquality(i);
1117   }
1118 }
1119 
1120 void IntegerRelation::convertIdKind(IdKind srcKind, unsigned idStart,
1121                                     unsigned idLimit, IdKind dstKind) {
1122   assert(idLimit <= getNumIdKind(srcKind) && "Invalid id range");
1123 
1124   if (idStart >= idLimit)
1125     return;
1126 
1127   // Append new local variables corresponding to the dimensions to be converted.
1128   unsigned newIdsBegin = getIdKindEnd(dstKind);
1129   unsigned convertCount = idLimit - idStart;
1130   appendId(dstKind, convertCount);
1131 
1132   // Swap the new local variables with dimensions.
1133   //
1134   // Essentially, this moves the information corresponding to the specified ids
1135   // of kind `srcKind` to the `convertCount` newly created ids of kind
1136   // `dstKind`. In particular, this moves the columns in the constraint
1137   // matrices, and zeros out the initially occupied columns (because the newly
1138   // created ids we're swapping with were zero-initialized).
1139   unsigned offset = getIdKindOffset(srcKind);
1140   for (unsigned i = 0; i < convertCount; ++i)
1141     swapId(offset + idStart + i, newIdsBegin + i);
1142 
1143   // Complete the move by deleting the initially occupied columns.
1144   removeIdRange(srcKind, idStart, idLimit);
1145 }
1146 
1147 void IntegerRelation::addBound(BoundType type, unsigned pos, int64_t value) {
1148   assert(pos < getNumCols());
1149   if (type == BoundType::EQ) {
1150     unsigned row = equalities.appendExtraRow();
1151     equalities(row, pos) = 1;
1152     equalities(row, getNumCols() - 1) = -value;
1153   } else {
1154     unsigned row = inequalities.appendExtraRow();
1155     inequalities(row, pos) = type == BoundType::LB ? 1 : -1;
1156     inequalities(row, getNumCols() - 1) =
1157         type == BoundType::LB ? -value : value;
1158   }
1159 }
1160 
1161 void IntegerRelation::addBound(BoundType type, ArrayRef<int64_t> expr,
1162                                int64_t value) {
1163   assert(type != BoundType::EQ && "EQ not implemented");
1164   assert(expr.size() == getNumCols());
1165   unsigned row = inequalities.appendExtraRow();
1166   for (unsigned i = 0, e = expr.size(); i < e; ++i)
1167     inequalities(row, i) = type == BoundType::LB ? expr[i] : -expr[i];
1168   inequalities(inequalities.getNumRows() - 1, getNumCols() - 1) +=
1169       type == BoundType::LB ? -value : value;
1170 }
1171 
1172 /// Adds a new local identifier as the floordiv of an affine function of other
1173 /// identifiers, the coefficients of which are provided in 'dividend' and with
1174 /// respect to a positive constant 'divisor'. Two constraints are added to the
1175 /// system to capture equivalence with the floordiv.
1176 ///      q = expr floordiv c    <=>   c*q <= expr <= c*q + c - 1.
1177 void IntegerRelation::addLocalFloorDiv(ArrayRef<int64_t> dividend,
1178                                        int64_t divisor) {
1179   assert(dividend.size() == getNumCols() && "incorrect dividend size");
1180   assert(divisor > 0 && "positive divisor expected");
1181 
1182   appendId(IdKind::Local);
1183 
1184   // Add two constraints for this new identifier 'q'.
1185   SmallVector<int64_t, 8> bound(dividend.size() + 1);
1186 
1187   // dividend - q * divisor >= 0
1188   std::copy(dividend.begin(), dividend.begin() + dividend.size() - 1,
1189             bound.begin());
1190   bound.back() = dividend.back();
1191   bound[getNumIds() - 1] = -divisor;
1192   addInequality(bound);
1193 
1194   // -dividend +qdivisor * q + divisor - 1 >= 0
1195   std::transform(bound.begin(), bound.end(), bound.begin(),
1196                  std::negate<int64_t>());
1197   bound[bound.size() - 1] += divisor - 1;
1198   addInequality(bound);
1199 }
1200 
1201 /// Finds an equality that equates the specified identifier to a constant.
1202 /// Returns the position of the equality row. If 'symbolic' is set to true,
1203 /// symbols are also treated like a constant, i.e., an affine function of the
1204 /// symbols is also treated like a constant. Returns -1 if such an equality
1205 /// could not be found.
1206 static int findEqualityToConstant(const IntegerRelation &cst, unsigned pos,
1207                                   bool symbolic = false) {
1208   assert(pos < cst.getNumIds() && "invalid position");
1209   for (unsigned r = 0, e = cst.getNumEqualities(); r < e; r++) {
1210     int64_t v = cst.atEq(r, pos);
1211     if (v * v != 1)
1212       continue;
1213     unsigned c;
1214     unsigned f = symbolic ? cst.getNumDimIds() : cst.getNumIds();
1215     // This checks for zeros in all positions other than 'pos' in [0, f)
1216     for (c = 0; c < f; c++) {
1217       if (c == pos)
1218         continue;
1219       if (cst.atEq(r, c) != 0) {
1220         // Dependent on another identifier.
1221         break;
1222       }
1223     }
1224     if (c == f)
1225       // Equality is free of other identifiers.
1226       return r;
1227   }
1228   return -1;
1229 }
1230 
1231 LogicalResult IntegerRelation::constantFoldId(unsigned pos) {
1232   assert(pos < getNumIds() && "invalid position");
1233   int rowIdx;
1234   if ((rowIdx = findEqualityToConstant(*this, pos)) == -1)
1235     return failure();
1236 
1237   // atEq(rowIdx, pos) is either -1 or 1.
1238   assert(atEq(rowIdx, pos) * atEq(rowIdx, pos) == 1);
1239   int64_t constVal = -atEq(rowIdx, getNumCols() - 1) / atEq(rowIdx, pos);
1240   setAndEliminate(pos, constVal);
1241   return success();
1242 }
1243 
1244 void IntegerRelation::constantFoldIdRange(unsigned pos, unsigned num) {
1245   for (unsigned s = pos, t = pos, e = pos + num; s < e; s++) {
1246     if (failed(constantFoldId(t)))
1247       t++;
1248   }
1249 }
1250 
1251 /// Returns a non-negative constant bound on the extent (upper bound - lower
1252 /// bound) of the specified identifier if it is found to be a constant; returns
1253 /// None if it's not a constant. This methods treats symbolic identifiers
1254 /// specially, i.e., it looks for constant differences between affine
1255 /// expressions involving only the symbolic identifiers. See comments at
1256 /// function definition for example. 'lb', if provided, is set to the lower
1257 /// bound associated with the constant difference. Note that 'lb' is purely
1258 /// symbolic and thus will contain the coefficients of the symbolic identifiers
1259 /// and the constant coefficient.
1260 //  Egs: 0 <= i <= 15, return 16.
1261 //       s0 + 2 <= i <= s0 + 17, returns 16. (s0 has to be a symbol)
1262 //       s0 + s1 + 16 <= d0 <= s0 + s1 + 31, returns 16.
1263 //       s0 - 7 <= 8*j <= s0 returns 1 with lb = s0, lbDivisor = 8 (since lb =
1264 //       ceil(s0 - 7 / 8) = floor(s0 / 8)).
1265 Optional<int64_t> IntegerRelation::getConstantBoundOnDimSize(
1266     unsigned pos, SmallVectorImpl<int64_t> *lb, int64_t *boundFloorDivisor,
1267     SmallVectorImpl<int64_t> *ub, unsigned *minLbPos,
1268     unsigned *minUbPos) const {
1269   assert(pos < getNumDimIds() && "Invalid identifier position");
1270 
1271   // Find an equality for 'pos'^th identifier that equates it to some function
1272   // of the symbolic identifiers (+ constant).
1273   int eqPos = findEqualityToConstant(*this, pos, /*symbolic=*/true);
1274   if (eqPos != -1) {
1275     auto eq = getEquality(eqPos);
1276     // If the equality involves a local var, punt for now.
1277     // TODO: this can be handled in the future by using the explicit
1278     // representation of the local vars.
1279     if (!std::all_of(eq.begin() + getNumDimAndSymbolIds(), eq.end() - 1,
1280                      [](int64_t coeff) { return coeff == 0; }))
1281       return None;
1282 
1283     // This identifier can only take a single value.
1284     if (lb) {
1285       // Set lb to that symbolic value.
1286       lb->resize(getNumSymbolIds() + 1);
1287       if (ub)
1288         ub->resize(getNumSymbolIds() + 1);
1289       for (unsigned c = 0, f = getNumSymbolIds() + 1; c < f; c++) {
1290         int64_t v = atEq(eqPos, pos);
1291         // atEq(eqRow, pos) is either -1 or 1.
1292         assert(v * v == 1);
1293         (*lb)[c] = v < 0 ? atEq(eqPos, getNumDimIds() + c) / -v
1294                          : -atEq(eqPos, getNumDimIds() + c) / v;
1295         // Since this is an equality, ub = lb.
1296         if (ub)
1297           (*ub)[c] = (*lb)[c];
1298       }
1299       assert(boundFloorDivisor &&
1300              "both lb and divisor or none should be provided");
1301       *boundFloorDivisor = 1;
1302     }
1303     if (minLbPos)
1304       *minLbPos = eqPos;
1305     if (minUbPos)
1306       *minUbPos = eqPos;
1307     return 1;
1308   }
1309 
1310   // Check if the identifier appears at all in any of the inequalities.
1311   unsigned r, e;
1312   for (r = 0, e = getNumInequalities(); r < e; r++) {
1313     if (atIneq(r, pos) != 0)
1314       break;
1315   }
1316   if (r == e)
1317     // If it doesn't, there isn't a bound on it.
1318     return None;
1319 
1320   // Positions of constraints that are lower/upper bounds on the variable.
1321   SmallVector<unsigned, 4> lbIndices, ubIndices;
1322 
1323   // Gather all symbolic lower bounds and upper bounds of the variable, i.e.,
1324   // the bounds can only involve symbolic (and local) identifiers. Since the
1325   // canonical form c_1*x_1 + c_2*x_2 + ... + c_0 >= 0, a constraint is a lower
1326   // bound for x_i if c_i >= 1, and an upper bound if c_i <= -1.
1327   getLowerAndUpperBoundIndices(pos, &lbIndices, &ubIndices,
1328                                /*eqIndices=*/nullptr, /*offset=*/0,
1329                                /*num=*/getNumDimIds());
1330 
1331   Optional<int64_t> minDiff = None;
1332   unsigned minLbPosition = 0, minUbPosition = 0;
1333   for (auto ubPos : ubIndices) {
1334     for (auto lbPos : lbIndices) {
1335       // Look for a lower bound and an upper bound that only differ by a
1336       // constant, i.e., pairs of the form  0 <= c_pos - f(c_i's) <= diffConst.
1337       // For example, if ii is the pos^th variable, we are looking for
1338       // constraints like ii >= i, ii <= ii + 50, 50 being the difference. The
1339       // minimum among all such constant differences is kept since that's the
1340       // constant bounding the extent of the pos^th variable.
1341       unsigned j, e;
1342       for (j = 0, e = getNumCols() - 1; j < e; j++)
1343         if (atIneq(ubPos, j) != -atIneq(lbPos, j)) {
1344           break;
1345         }
1346       if (j < getNumCols() - 1)
1347         continue;
1348       int64_t diff = ceilDiv(atIneq(ubPos, getNumCols() - 1) +
1349                                  atIneq(lbPos, getNumCols() - 1) + 1,
1350                              atIneq(lbPos, pos));
1351       // This bound is non-negative by definition.
1352       diff = std::max<int64_t>(diff, 0);
1353       if (minDiff == None || diff < minDiff) {
1354         minDiff = diff;
1355         minLbPosition = lbPos;
1356         minUbPosition = ubPos;
1357       }
1358     }
1359   }
1360   if (lb && minDiff.hasValue()) {
1361     // Set lb to the symbolic lower bound.
1362     lb->resize(getNumSymbolIds() + 1);
1363     if (ub)
1364       ub->resize(getNumSymbolIds() + 1);
1365     // The lower bound is the ceildiv of the lb constraint over the coefficient
1366     // of the variable at 'pos'. We express the ceildiv equivalently as a floor
1367     // for uniformity. For eg., if the lower bound constraint was: 32*d0 - N +
1368     // 31 >= 0, the lower bound for d0 is ceil(N - 31, 32), i.e., floor(N, 32).
1369     *boundFloorDivisor = atIneq(minLbPosition, pos);
1370     assert(*boundFloorDivisor == -atIneq(minUbPosition, pos));
1371     for (unsigned c = 0, e = getNumSymbolIds() + 1; c < e; c++) {
1372       (*lb)[c] = -atIneq(minLbPosition, getNumDimIds() + c);
1373     }
1374     if (ub) {
1375       for (unsigned c = 0, e = getNumSymbolIds() + 1; c < e; c++)
1376         (*ub)[c] = atIneq(minUbPosition, getNumDimIds() + c);
1377     }
1378     // The lower bound leads to a ceildiv while the upper bound is a floordiv
1379     // whenever the coefficient at pos != 1. ceildiv (val / d) = floordiv (val +
1380     // d - 1 / d); hence, the addition of 'atIneq(minLbPosition, pos) - 1' to
1381     // the constant term for the lower bound.
1382     (*lb)[getNumSymbolIds()] += atIneq(minLbPosition, pos) - 1;
1383   }
1384   if (minLbPos)
1385     *minLbPos = minLbPosition;
1386   if (minUbPos)
1387     *minUbPos = minUbPosition;
1388   return minDiff;
1389 }
1390 
1391 template <bool isLower>
1392 Optional<int64_t>
1393 IntegerRelation::computeConstantLowerOrUpperBound(unsigned pos) {
1394   assert(pos < getNumIds() && "invalid position");
1395   // Project to 'pos'.
1396   projectOut(0, pos);
1397   projectOut(1, getNumIds() - 1);
1398   // Check if there's an equality equating the '0'^th identifier to a constant.
1399   int eqRowIdx = findEqualityToConstant(*this, 0, /*symbolic=*/false);
1400   if (eqRowIdx != -1)
1401     // atEq(rowIdx, 0) is either -1 or 1.
1402     return -atEq(eqRowIdx, getNumCols() - 1) / atEq(eqRowIdx, 0);
1403 
1404   // Check if the identifier appears at all in any of the inequalities.
1405   unsigned r, e;
1406   for (r = 0, e = getNumInequalities(); r < e; r++) {
1407     if (atIneq(r, 0) != 0)
1408       break;
1409   }
1410   if (r == e)
1411     // If it doesn't, there isn't a bound on it.
1412     return None;
1413 
1414   Optional<int64_t> minOrMaxConst = None;
1415 
1416   // Take the max across all const lower bounds (or min across all constant
1417   // upper bounds).
1418   for (unsigned r = 0, e = getNumInequalities(); r < e; r++) {
1419     if (isLower) {
1420       if (atIneq(r, 0) <= 0)
1421         // Not a lower bound.
1422         continue;
1423     } else if (atIneq(r, 0) >= 0) {
1424       // Not an upper bound.
1425       continue;
1426     }
1427     unsigned c, f;
1428     for (c = 0, f = getNumCols() - 1; c < f; c++)
1429       if (c != 0 && atIneq(r, c) != 0)
1430         break;
1431     if (c < getNumCols() - 1)
1432       // Not a constant bound.
1433       continue;
1434 
1435     int64_t boundConst =
1436         isLower ? mlir::ceilDiv(-atIneq(r, getNumCols() - 1), atIneq(r, 0))
1437                 : mlir::floorDiv(atIneq(r, getNumCols() - 1), -atIneq(r, 0));
1438     if (isLower) {
1439       if (minOrMaxConst == None || boundConst > minOrMaxConst)
1440         minOrMaxConst = boundConst;
1441     } else {
1442       if (minOrMaxConst == None || boundConst < minOrMaxConst)
1443         minOrMaxConst = boundConst;
1444     }
1445   }
1446   return minOrMaxConst;
1447 }
1448 
1449 Optional<int64_t> IntegerRelation::getConstantBound(BoundType type,
1450                                                     unsigned pos) const {
1451   if (type == BoundType::LB)
1452     return IntegerRelation(*this)
1453         .computeConstantLowerOrUpperBound</*isLower=*/true>(pos);
1454   if (type == BoundType::UB)
1455     return IntegerRelation(*this)
1456         .computeConstantLowerOrUpperBound</*isLower=*/false>(pos);
1457 
1458   assert(type == BoundType::EQ && "expected EQ");
1459   Optional<int64_t> lb =
1460       IntegerRelation(*this).computeConstantLowerOrUpperBound</*isLower=*/true>(
1461           pos);
1462   Optional<int64_t> ub =
1463       IntegerRelation(*this)
1464           .computeConstantLowerOrUpperBound</*isLower=*/false>(pos);
1465   return (lb && ub && *lb == *ub) ? Optional<int64_t>(*ub) : None;
1466 }
1467 
1468 // A simple (naive and conservative) check for hyper-rectangularity.
1469 bool IntegerRelation::isHyperRectangular(unsigned pos, unsigned num) const {
1470   assert(pos < getNumCols() - 1);
1471   // Check for two non-zero coefficients in the range [pos, pos + sum).
1472   for (unsigned r = 0, e = getNumInequalities(); r < e; r++) {
1473     unsigned sum = 0;
1474     for (unsigned c = pos; c < pos + num; c++) {
1475       if (atIneq(r, c) != 0)
1476         sum++;
1477     }
1478     if (sum > 1)
1479       return false;
1480   }
1481   for (unsigned r = 0, e = getNumEqualities(); r < e; r++) {
1482     unsigned sum = 0;
1483     for (unsigned c = pos; c < pos + num; c++) {
1484       if (atEq(r, c) != 0)
1485         sum++;
1486     }
1487     if (sum > 1)
1488       return false;
1489   }
1490   return true;
1491 }
1492 
1493 /// Removes duplicate constraints, trivially true constraints, and constraints
1494 /// that can be detected as redundant as a result of differing only in their
1495 /// constant term part. A constraint of the form <non-negative constant> >= 0 is
1496 /// considered trivially true.
1497 //  Uses a DenseSet to hash and detect duplicates followed by a linear scan to
1498 //  remove duplicates in place.
1499 void IntegerRelation::removeTrivialRedundancy() {
1500   gcdTightenInequalities();
1501   normalizeConstraintsByGCD();
1502 
1503   // A map used to detect redundancy stemming from constraints that only differ
1504   // in their constant term. The value stored is <row position, const term>
1505   // for a given row.
1506   SmallDenseMap<ArrayRef<int64_t>, std::pair<unsigned, int64_t>>
1507       rowsWithoutConstTerm;
1508   // To unique rows.
1509   SmallDenseSet<ArrayRef<int64_t>, 8> rowSet;
1510 
1511   // Check if constraint is of the form <non-negative-constant> >= 0.
1512   auto isTriviallyValid = [&](unsigned r) -> bool {
1513     for (unsigned c = 0, e = getNumCols() - 1; c < e; c++) {
1514       if (atIneq(r, c) != 0)
1515         return false;
1516     }
1517     return atIneq(r, getNumCols() - 1) >= 0;
1518   };
1519 
1520   // Detect and mark redundant constraints.
1521   SmallVector<bool, 256> redunIneq(getNumInequalities(), false);
1522   for (unsigned r = 0, e = getNumInequalities(); r < e; r++) {
1523     int64_t *rowStart = &inequalities(r, 0);
1524     auto row = ArrayRef<int64_t>(rowStart, getNumCols());
1525     if (isTriviallyValid(r) || !rowSet.insert(row).second) {
1526       redunIneq[r] = true;
1527       continue;
1528     }
1529 
1530     // Among constraints that only differ in the constant term part, mark
1531     // everything other than the one with the smallest constant term redundant.
1532     // (eg: among i - 16j - 5 >= 0, i - 16j - 1 >=0, i - 16j - 7 >= 0, the
1533     // former two are redundant).
1534     int64_t constTerm = atIneq(r, getNumCols() - 1);
1535     auto rowWithoutConstTerm = ArrayRef<int64_t>(rowStart, getNumCols() - 1);
1536     const auto &ret =
1537         rowsWithoutConstTerm.insert({rowWithoutConstTerm, {r, constTerm}});
1538     if (!ret.second) {
1539       // Check if the other constraint has a higher constant term.
1540       auto &val = ret.first->second;
1541       if (val.second > constTerm) {
1542         // The stored row is redundant. Mark it so, and update with this one.
1543         redunIneq[val.first] = true;
1544         val = {r, constTerm};
1545       } else {
1546         // The one stored makes this one redundant.
1547         redunIneq[r] = true;
1548       }
1549     }
1550   }
1551 
1552   // Scan to get rid of all rows marked redundant, in-place.
1553   unsigned pos = 0;
1554   for (unsigned r = 0, e = getNumInequalities(); r < e; r++)
1555     if (!redunIneq[r])
1556       inequalities.copyRow(r, pos++);
1557 
1558   inequalities.resizeVertically(pos);
1559 
1560   // TODO: consider doing this for equalities as well, but probably not worth
1561   // the savings.
1562 }
1563 
1564 #undef DEBUG_TYPE
1565 #define DEBUG_TYPE "fm"
1566 
1567 /// Eliminates identifier at the specified position using Fourier-Motzkin
1568 /// variable elimination. This technique is exact for rational spaces but
1569 /// conservative (in "rare" cases) for integer spaces. The operation corresponds
1570 /// to a projection operation yielding the (convex) set of integer points
1571 /// contained in the rational shadow of the set. An emptiness test that relies
1572 /// on this method will guarantee emptiness, i.e., it disproves the existence of
1573 /// a solution if it says it's empty.
1574 /// If a non-null isResultIntegerExact is passed, it is set to true if the
1575 /// result is also integer exact. If it's set to false, the obtained solution
1576 /// *may* not be exact, i.e., it may contain integer points that do not have an
1577 /// integer pre-image in the original set.
1578 ///
1579 /// Eg:
1580 /// j >= 0, j <= i + 1
1581 /// i >= 0, i <= N + 1
1582 /// Eliminating i yields,
1583 ///   j >= 0, 0 <= N + 1, j - 1 <= N + 1
1584 ///
1585 /// If darkShadow = true, this method computes the dark shadow on elimination;
1586 /// the dark shadow is a convex integer subset of the exact integer shadow. A
1587 /// non-empty dark shadow proves the existence of an integer solution. The
1588 /// elimination in such a case could however be an under-approximation, and thus
1589 /// should not be used for scanning sets or used by itself for dependence
1590 /// checking.
1591 ///
1592 /// Eg: 2-d set, * represents grid points, 'o' represents a point in the set.
1593 ///            ^
1594 ///            |
1595 ///            | * * * * o o
1596 ///         i  | * * o o o o
1597 ///            | o * * * * *
1598 ///            --------------->
1599 ///                 j ->
1600 ///
1601 /// Eliminating i from this system (projecting on the j dimension):
1602 /// rational shadow / integer light shadow:  1 <= j <= 6
1603 /// dark shadow:                             3 <= j <= 6
1604 /// exact integer shadow:                    j = 1 \union  3 <= j <= 6
1605 /// holes/splinters:                         j = 2
1606 ///
1607 /// darkShadow = false, isResultIntegerExact = nullptr are default values.
1608 // TODO: a slight modification to yield dark shadow version of FM (tightened),
1609 // which can prove the existence of a solution if there is one.
1610 void IntegerRelation::fourierMotzkinEliminate(unsigned pos, bool darkShadow,
1611                                               bool *isResultIntegerExact) {
1612   LLVM_DEBUG(llvm::dbgs() << "FM input (eliminate pos " << pos << "):\n");
1613   LLVM_DEBUG(dump());
1614   assert(pos < getNumIds() && "invalid position");
1615   assert(hasConsistentState());
1616 
1617   // Check if this identifier can be eliminated through a substitution.
1618   for (unsigned r = 0, e = getNumEqualities(); r < e; r++) {
1619     if (atEq(r, pos) != 0) {
1620       // Use Gaussian elimination here (since we have an equality).
1621       LogicalResult ret = gaussianEliminateId(pos);
1622       (void)ret;
1623       assert(succeeded(ret) && "Gaussian elimination guaranteed to succeed");
1624       LLVM_DEBUG(llvm::dbgs() << "FM output (through Gaussian elimination):\n");
1625       LLVM_DEBUG(dump());
1626       return;
1627     }
1628   }
1629 
1630   // A fast linear time tightening.
1631   gcdTightenInequalities();
1632 
1633   // Check if the identifier appears at all in any of the inequalities.
1634   if (isColZero(pos)) {
1635     // If it doesn't appear, just remove the column and return.
1636     // TODO: refactor removeColumns to use it from here.
1637     removeId(pos);
1638     LLVM_DEBUG(llvm::dbgs() << "FM output:\n");
1639     LLVM_DEBUG(dump());
1640     return;
1641   }
1642 
1643   // Positions of constraints that are lower bounds on the variable.
1644   SmallVector<unsigned, 4> lbIndices;
1645   // Positions of constraints that are lower bounds on the variable.
1646   SmallVector<unsigned, 4> ubIndices;
1647   // Positions of constraints that do not involve the variable.
1648   std::vector<unsigned> nbIndices;
1649   nbIndices.reserve(getNumInequalities());
1650 
1651   // Gather all lower bounds and upper bounds of the variable. Since the
1652   // canonical form c_1*x_1 + c_2*x_2 + ... + c_0 >= 0, a constraint is a lower
1653   // bound for x_i if c_i >= 1, and an upper bound if c_i <= -1.
1654   for (unsigned r = 0, e = getNumInequalities(); r < e; r++) {
1655     if (atIneq(r, pos) == 0) {
1656       // Id does not appear in bound.
1657       nbIndices.push_back(r);
1658     } else if (atIneq(r, pos) >= 1) {
1659       // Lower bound.
1660       lbIndices.push_back(r);
1661     } else {
1662       // Upper bound.
1663       ubIndices.push_back(r);
1664     }
1665   }
1666 
1667   // Set the number of dimensions, symbols, locals in the resulting system.
1668   unsigned newNumDomain =
1669       getNumDomainIds() - getIdKindOverlap(IdKind::Domain, pos, pos + 1);
1670   unsigned newNumRange =
1671       getNumRangeIds() - getIdKindOverlap(IdKind::Range, pos, pos + 1);
1672   unsigned newNumSymbols =
1673       getNumSymbolIds() - getIdKindOverlap(IdKind::Symbol, pos, pos + 1);
1674   unsigned newNumLocals =
1675       getNumLocalIds() - getIdKindOverlap(IdKind::Local, pos, pos + 1);
1676 
1677   /// Create the new system which has one identifier less.
1678   IntegerRelation newRel(lbIndices.size() * ubIndices.size() + nbIndices.size(),
1679                          getNumEqualities(), getNumCols() - 1, newNumDomain,
1680                          newNumRange, newNumSymbols, newNumLocals);
1681 
1682   // This will be used to check if the elimination was integer exact.
1683   unsigned lcmProducts = 1;
1684 
1685   // Let x be the variable we are eliminating.
1686   // For each lower bound, lb <= c_l*x, and each upper bound c_u*x <= ub, (note
1687   // that c_l, c_u >= 1) we have:
1688   // lb*lcm(c_l, c_u)/c_l <= lcm(c_l, c_u)*x <= ub*lcm(c_l, c_u)/c_u
1689   // We thus generate a constraint:
1690   // lcm(c_l, c_u)/c_l*lb <= lcm(c_l, c_u)/c_u*ub.
1691   // Note if c_l = c_u = 1, all integer points captured by the resulting
1692   // constraint correspond to integer points in the original system (i.e., they
1693   // have integer pre-images). Hence, if the lcm's are all 1, the elimination is
1694   // integer exact.
1695   for (auto ubPos : ubIndices) {
1696     for (auto lbPos : lbIndices) {
1697       SmallVector<int64_t, 4> ineq;
1698       ineq.reserve(newRel.getNumCols());
1699       int64_t lbCoeff = atIneq(lbPos, pos);
1700       // Note that in the comments above, ubCoeff is the negation of the
1701       // coefficient in the canonical form as the view taken here is that of the
1702       // term being moved to the other size of '>='.
1703       int64_t ubCoeff = -atIneq(ubPos, pos);
1704       // TODO: refactor this loop to avoid all branches inside.
1705       for (unsigned l = 0, e = getNumCols(); l < e; l++) {
1706         if (l == pos)
1707           continue;
1708         assert(lbCoeff >= 1 && ubCoeff >= 1 && "bounds wrongly identified");
1709         int64_t lcm = mlir::lcm(lbCoeff, ubCoeff);
1710         ineq.push_back(atIneq(ubPos, l) * (lcm / ubCoeff) +
1711                        atIneq(lbPos, l) * (lcm / lbCoeff));
1712         lcmProducts *= lcm;
1713       }
1714       if (darkShadow) {
1715         // The dark shadow is a convex subset of the exact integer shadow. If
1716         // there is a point here, it proves the existence of a solution.
1717         ineq[ineq.size() - 1] += lbCoeff * ubCoeff - lbCoeff - ubCoeff + 1;
1718       }
1719       // TODO: we need to have a way to add inequalities in-place in
1720       // IntegerRelation instead of creating and copying over.
1721       newRel.addInequality(ineq);
1722     }
1723   }
1724 
1725   LLVM_DEBUG(llvm::dbgs() << "FM isResultIntegerExact: " << (lcmProducts == 1)
1726                           << "\n");
1727   if (lcmProducts == 1 && isResultIntegerExact)
1728     *isResultIntegerExact = true;
1729 
1730   // Copy over the constraints not involving this variable.
1731   for (auto nbPos : nbIndices) {
1732     SmallVector<int64_t, 4> ineq;
1733     ineq.reserve(getNumCols() - 1);
1734     for (unsigned l = 0, e = getNumCols(); l < e; l++) {
1735       if (l == pos)
1736         continue;
1737       ineq.push_back(atIneq(nbPos, l));
1738     }
1739     newRel.addInequality(ineq);
1740   }
1741 
1742   assert(newRel.getNumConstraints() ==
1743          lbIndices.size() * ubIndices.size() + nbIndices.size());
1744 
1745   // Copy over the equalities.
1746   for (unsigned r = 0, e = getNumEqualities(); r < e; r++) {
1747     SmallVector<int64_t, 4> eq;
1748     eq.reserve(newRel.getNumCols());
1749     for (unsigned l = 0, e = getNumCols(); l < e; l++) {
1750       if (l == pos)
1751         continue;
1752       eq.push_back(atEq(r, l));
1753     }
1754     newRel.addEquality(eq);
1755   }
1756 
1757   // GCD tightening and normalization allows detection of more trivially
1758   // redundant constraints.
1759   newRel.gcdTightenInequalities();
1760   newRel.normalizeConstraintsByGCD();
1761   newRel.removeTrivialRedundancy();
1762   clearAndCopyFrom(newRel);
1763   LLVM_DEBUG(llvm::dbgs() << "FM output:\n");
1764   LLVM_DEBUG(dump());
1765 }
1766 
1767 #undef DEBUG_TYPE
1768 #define DEBUG_TYPE "presburger"
1769 
1770 void IntegerRelation::projectOut(unsigned pos, unsigned num) {
1771   if (num == 0)
1772     return;
1773 
1774   // 'pos' can be at most getNumCols() - 2 if num > 0.
1775   assert((getNumCols() < 2 || pos <= getNumCols() - 2) && "invalid position");
1776   assert(pos + num < getNumCols() && "invalid range");
1777 
1778   // Eliminate as many identifiers as possible using Gaussian elimination.
1779   unsigned currentPos = pos;
1780   unsigned numToEliminate = num;
1781   unsigned numGaussianEliminated = 0;
1782 
1783   while (currentPos < getNumIds()) {
1784     unsigned curNumEliminated =
1785         gaussianEliminateIds(currentPos, currentPos + numToEliminate);
1786     ++currentPos;
1787     numToEliminate -= curNumEliminated + 1;
1788     numGaussianEliminated += curNumEliminated;
1789   }
1790 
1791   // Eliminate the remaining using Fourier-Motzkin.
1792   for (unsigned i = 0; i < num - numGaussianEliminated; i++) {
1793     unsigned numToEliminate = num - numGaussianEliminated - i;
1794     fourierMotzkinEliminate(
1795         getBestIdToEliminate(*this, pos, pos + numToEliminate));
1796   }
1797 
1798   // Fast/trivial simplifications.
1799   gcdTightenInequalities();
1800   // Normalize constraints after tightening since the latter impacts this, but
1801   // not the other way round.
1802   normalizeConstraintsByGCD();
1803 }
1804 
1805 namespace {
1806 
1807 enum BoundCmpResult { Greater, Less, Equal, Unknown };
1808 
1809 /// Compares two affine bounds whose coefficients are provided in 'first' and
1810 /// 'second'. The last coefficient is the constant term.
1811 static BoundCmpResult compareBounds(ArrayRef<int64_t> a, ArrayRef<int64_t> b) {
1812   assert(a.size() == b.size());
1813 
1814   // For the bounds to be comparable, their corresponding identifier
1815   // coefficients should be equal; the constant terms are then compared to
1816   // determine less/greater/equal.
1817 
1818   if (!std::equal(a.begin(), a.end() - 1, b.begin()))
1819     return Unknown;
1820 
1821   if (a.back() == b.back())
1822     return Equal;
1823 
1824   return a.back() < b.back() ? Less : Greater;
1825 }
1826 } // namespace
1827 
1828 // Returns constraints that are common to both A & B.
1829 static void getCommonConstraints(const IntegerRelation &a,
1830                                  const IntegerRelation &b, IntegerRelation &c) {
1831   c = IntegerRelation(a.getNumDomainIds(), a.getNumRangeIds(),
1832                       a.getNumSymbolIds(), a.getNumLocalIds());
1833   // a naive O(n^2) check should be enough here given the input sizes.
1834   for (unsigned r = 0, e = a.getNumInequalities(); r < e; ++r) {
1835     for (unsigned s = 0, f = b.getNumInequalities(); s < f; ++s) {
1836       if (a.getInequality(r) == b.getInequality(s)) {
1837         c.addInequality(a.getInequality(r));
1838         break;
1839       }
1840     }
1841   }
1842   for (unsigned r = 0, e = a.getNumEqualities(); r < e; ++r) {
1843     for (unsigned s = 0, f = b.getNumEqualities(); s < f; ++s) {
1844       if (a.getEquality(r) == b.getEquality(s)) {
1845         c.addEquality(a.getEquality(r));
1846         break;
1847       }
1848     }
1849   }
1850 }
1851 
1852 // Computes the bounding box with respect to 'other' by finding the min of the
1853 // lower bounds and the max of the upper bounds along each of the dimensions.
1854 LogicalResult
1855 IntegerRelation::unionBoundingBox(const IntegerRelation &otherCst) {
1856   assert(PresburgerLocalSpace::isEqual(otherCst) && "Spaces should match.");
1857   assert(getNumLocalIds() == 0 && "local ids not supported yet here");
1858 
1859   // Get the constraints common to both systems; these will be added as is to
1860   // the union.
1861   IntegerRelation commonCst;
1862   getCommonConstraints(*this, otherCst, commonCst);
1863 
1864   std::vector<SmallVector<int64_t, 8>> boundingLbs;
1865   std::vector<SmallVector<int64_t, 8>> boundingUbs;
1866   boundingLbs.reserve(2 * getNumDimIds());
1867   boundingUbs.reserve(2 * getNumDimIds());
1868 
1869   // To hold lower and upper bounds for each dimension.
1870   SmallVector<int64_t, 4> lb, otherLb, ub, otherUb;
1871   // To compute min of lower bounds and max of upper bounds for each dimension.
1872   SmallVector<int64_t, 4> minLb(getNumSymbolIds() + 1);
1873   SmallVector<int64_t, 4> maxUb(getNumSymbolIds() + 1);
1874   // To compute final new lower and upper bounds for the union.
1875   SmallVector<int64_t, 8> newLb(getNumCols()), newUb(getNumCols());
1876 
1877   int64_t lbFloorDivisor, otherLbFloorDivisor;
1878   for (unsigned d = 0, e = getNumDimIds(); d < e; ++d) {
1879     auto extent = getConstantBoundOnDimSize(d, &lb, &lbFloorDivisor, &ub);
1880     if (!extent.hasValue())
1881       // TODO: symbolic extents when necessary.
1882       // TODO: handle union if a dimension is unbounded.
1883       return failure();
1884 
1885     auto otherExtent = otherCst.getConstantBoundOnDimSize(
1886         d, &otherLb, &otherLbFloorDivisor, &otherUb);
1887     if (!otherExtent.hasValue() || lbFloorDivisor != otherLbFloorDivisor)
1888       // TODO: symbolic extents when necessary.
1889       return failure();
1890 
1891     assert(lbFloorDivisor > 0 && "divisor always expected to be positive");
1892 
1893     auto res = compareBounds(lb, otherLb);
1894     // Identify min.
1895     if (res == BoundCmpResult::Less || res == BoundCmpResult::Equal) {
1896       minLb = lb;
1897       // Since the divisor is for a floordiv, we need to convert to ceildiv,
1898       // i.e., i >= expr floordiv div <=> i >= (expr - div + 1) ceildiv div <=>
1899       // div * i >= expr - div + 1.
1900       minLb.back() -= lbFloorDivisor - 1;
1901     } else if (res == BoundCmpResult::Greater) {
1902       minLb = otherLb;
1903       minLb.back() -= otherLbFloorDivisor - 1;
1904     } else {
1905       // Uncomparable - check for constant lower/upper bounds.
1906       auto constLb = getConstantBound(BoundType::LB, d);
1907       auto constOtherLb = otherCst.getConstantBound(BoundType::LB, d);
1908       if (!constLb.hasValue() || !constOtherLb.hasValue())
1909         return failure();
1910       std::fill(minLb.begin(), minLb.end(), 0);
1911       minLb.back() = std::min(constLb.getValue(), constOtherLb.getValue());
1912     }
1913 
1914     // Do the same for ub's but max of upper bounds. Identify max.
1915     auto uRes = compareBounds(ub, otherUb);
1916     if (uRes == BoundCmpResult::Greater || uRes == BoundCmpResult::Equal) {
1917       maxUb = ub;
1918     } else if (uRes == BoundCmpResult::Less) {
1919       maxUb = otherUb;
1920     } else {
1921       // Uncomparable - check for constant lower/upper bounds.
1922       auto constUb = getConstantBound(BoundType::UB, d);
1923       auto constOtherUb = otherCst.getConstantBound(BoundType::UB, d);
1924       if (!constUb.hasValue() || !constOtherUb.hasValue())
1925         return failure();
1926       std::fill(maxUb.begin(), maxUb.end(), 0);
1927       maxUb.back() = std::max(constUb.getValue(), constOtherUb.getValue());
1928     }
1929 
1930     std::fill(newLb.begin(), newLb.end(), 0);
1931     std::fill(newUb.begin(), newUb.end(), 0);
1932 
1933     // The divisor for lb, ub, otherLb, otherUb at this point is lbDivisor,
1934     // and so it's the divisor for newLb and newUb as well.
1935     newLb[d] = lbFloorDivisor;
1936     newUb[d] = -lbFloorDivisor;
1937     // Copy over the symbolic part + constant term.
1938     std::copy(minLb.begin(), minLb.end(), newLb.begin() + getNumDimIds());
1939     std::transform(newLb.begin() + getNumDimIds(), newLb.end(),
1940                    newLb.begin() + getNumDimIds(), std::negate<int64_t>());
1941     std::copy(maxUb.begin(), maxUb.end(), newUb.begin() + getNumDimIds());
1942 
1943     boundingLbs.push_back(newLb);
1944     boundingUbs.push_back(newUb);
1945   }
1946 
1947   // Clear all constraints and add the lower/upper bounds for the bounding box.
1948   clearConstraints();
1949   for (unsigned d = 0, e = getNumDimIds(); d < e; ++d) {
1950     addInequality(boundingLbs[d]);
1951     addInequality(boundingUbs[d]);
1952   }
1953 
1954   // Add the constraints that were common to both systems.
1955   append(commonCst);
1956   removeTrivialRedundancy();
1957 
1958   // TODO: copy over pure symbolic constraints from this and 'other' over to the
1959   // union (since the above are just the union along dimensions); we shouldn't
1960   // be discarding any other constraints on the symbols.
1961 
1962   return success();
1963 }
1964 
1965 bool IntegerRelation::isColZero(unsigned pos) const {
1966   unsigned rowPos;
1967   return !findConstraintWithNonZeroAt(pos, /*isEq=*/false, &rowPos) &&
1968          !findConstraintWithNonZeroAt(pos, /*isEq=*/true, &rowPos);
1969 }
1970 
1971 /// Find positions of inequalities and equalities that do not have a coefficient
1972 /// for [pos, pos + num) identifiers.
1973 static void getIndependentConstraints(const IntegerRelation &cst, unsigned pos,
1974                                       unsigned num,
1975                                       SmallVectorImpl<unsigned> &nbIneqIndices,
1976                                       SmallVectorImpl<unsigned> &nbEqIndices) {
1977   assert(pos < cst.getNumIds() && "invalid start position");
1978   assert(pos + num <= cst.getNumIds() && "invalid limit");
1979 
1980   for (unsigned r = 0, e = cst.getNumInequalities(); r < e; r++) {
1981     // The bounds are to be independent of [offset, offset + num) columns.
1982     unsigned c;
1983     for (c = pos; c < pos + num; ++c) {
1984       if (cst.atIneq(r, c) != 0)
1985         break;
1986     }
1987     if (c == pos + num)
1988       nbIneqIndices.push_back(r);
1989   }
1990 
1991   for (unsigned r = 0, e = cst.getNumEqualities(); r < e; r++) {
1992     // The bounds are to be independent of [offset, offset + num) columns.
1993     unsigned c;
1994     for (c = pos; c < pos + num; ++c) {
1995       if (cst.atEq(r, c) != 0)
1996         break;
1997     }
1998     if (c == pos + num)
1999       nbEqIndices.push_back(r);
2000   }
2001 }
2002 
2003 void IntegerRelation::removeIndependentConstraints(unsigned pos, unsigned num) {
2004   assert(pos + num <= getNumIds() && "invalid range");
2005 
2006   // Remove constraints that are independent of these identifiers.
2007   SmallVector<unsigned, 4> nbIneqIndices, nbEqIndices;
2008   getIndependentConstraints(*this, /*pos=*/0, num, nbIneqIndices, nbEqIndices);
2009 
2010   // Iterate in reverse so that indices don't have to be updated.
2011   // TODO: This method can be made more efficient (because removal of each
2012   // inequality leads to much shifting/copying in the underlying buffer).
2013   for (auto nbIndex : llvm::reverse(nbIneqIndices))
2014     removeInequality(nbIndex);
2015   for (auto nbIndex : llvm::reverse(nbEqIndices))
2016     removeEquality(nbIndex);
2017 }
2018 
2019 void IntegerRelation::printSpace(raw_ostream &os) const {
2020   PresburgerLocalSpace::print(os);
2021   os << getNumConstraints() << " constraints\n";
2022 }
2023 
2024 void IntegerRelation::print(raw_ostream &os) const {
2025   assert(hasConsistentState());
2026   printSpace(os);
2027   for (unsigned i = 0, e = getNumEqualities(); i < e; ++i) {
2028     for (unsigned j = 0, f = getNumCols(); j < f; ++j) {
2029       os << atEq(i, j) << " ";
2030     }
2031     os << "= 0\n";
2032   }
2033   for (unsigned i = 0, e = getNumInequalities(); i < e; ++i) {
2034     for (unsigned j = 0, f = getNumCols(); j < f; ++j) {
2035       os << atIneq(i, j) << " ";
2036     }
2037     os << ">= 0\n";
2038   }
2039   os << '\n';
2040 }
2041 
2042 void IntegerRelation::dump() const { print(llvm::errs()); }
2043 
2044 unsigned IntegerPolyhedron::insertId(IdKind kind, unsigned pos, unsigned num) {
2045   assert((kind != IdKind::Domain || num == 0) &&
2046          "Domain has to be zero in a set");
2047   return IntegerRelation::insertId(kind, pos, num);
2048 }
2049