xref: /llvm-project/mlir/lib/Analysis/Presburger/LinearTransform.cpp (revision 266a5a9cb9daa96c1eeaebc18e10f5a37d638734)
18506c8c1SGroverkss //===- LinearTransform.cpp - MLIR LinearTransform Class -------------------===//
28506c8c1SGroverkss //
38506c8c1SGroverkss // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
48506c8c1SGroverkss // See https://llvm.org/LICENSE.txt for license information.
58506c8c1SGroverkss // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
68506c8c1SGroverkss //
78506c8c1SGroverkss //===----------------------------------------------------------------------===//
88506c8c1SGroverkss 
98506c8c1SGroverkss #include "mlir/Analysis/Presburger/LinearTransform.h"
10bb901355SGroverkss #include "mlir/Analysis/Presburger/IntegerRelation.h"
112ee87cd6SMehdi Amini #include "mlir/Analysis/Presburger/Matrix.h"
122ee87cd6SMehdi Amini #include <utility>
138506c8c1SGroverkss 
140c1f6865SGroverkss using namespace mlir;
150c1f6865SGroverkss using namespace presburger;
168506c8c1SGroverkss 
17c1b99746SAbhinav271828 LinearTransform::LinearTransform(IntMatrix &&oMatrix) : matrix(oMatrix) {}
18c1b99746SAbhinav271828 LinearTransform::LinearTransform(const IntMatrix &oMatrix) : matrix(oMatrix) {}
198506c8c1SGroverkss 
20b696e25aSGroverkss std::pair<unsigned, LinearTransform>
21c1b99746SAbhinav271828 LinearTransform::makeTransformToColumnEchelon(const IntMatrix &m) {
22b696e25aSGroverkss   // Compute the hermite normal form of m. This, is by definition, is in column
23b696e25aSGroverkss   // echelon form.
24b696e25aSGroverkss   auto [h, u] = m.computeHermiteNormalForm();
25b696e25aSGroverkss 
26b696e25aSGroverkss   // Since the matrix is in column ecehlon form, a zero column means the rest of
27b696e25aSGroverkss   // the columns are zero. Thus, once we find a zero column, we can stop.
28b696e25aSGroverkss   unsigned col, e;
29b696e25aSGroverkss   for (col = 0, e = m.getNumColumns(); col < e; ++col) {
30b696e25aSGroverkss     bool zeroCol = true;
31b696e25aSGroverkss     for (unsigned row = 0, f = m.getNumRows(); row < f; ++row) {
32b696e25aSGroverkss       if (h(row, col) != 0) {
33b696e25aSGroverkss         zeroCol = false;
34b696e25aSGroverkss         break;
35b696e25aSGroverkss       }
368506c8c1SGroverkss     }
378506c8c1SGroverkss 
38b696e25aSGroverkss     if (zeroCol)
398506c8c1SGroverkss       break;
408506c8c1SGroverkss   }
418506c8c1SGroverkss 
42b696e25aSGroverkss   return {col, LinearTransform(std::move(u))};
438506c8c1SGroverkss }
448506c8c1SGroverkss 
45bb901355SGroverkss IntegerRelation LinearTransform::applyTo(const IntegerRelation &rel) const {
46a5a598beSGroverkss   IntegerRelation result(rel.getSpace());
478506c8c1SGroverkss 
48bb901355SGroverkss   for (unsigned i = 0, e = rel.getNumEqualities(); i < e; ++i) {
491a0e67d7SRamkumar Ramachandra     ArrayRef<DynamicAPInt> eq = rel.getEquality(i);
508506c8c1SGroverkss 
511a0e67d7SRamkumar Ramachandra     const DynamicAPInt &c = eq.back();
528506c8c1SGroverkss 
531a0e67d7SRamkumar Ramachandra     SmallVector<DynamicAPInt, 8> newEq = preMultiplyWithRow(eq.drop_back());
54*266a5a9cSRamkumar Ramachandra     newEq.emplace_back(c);
558506c8c1SGroverkss     result.addEquality(newEq);
568506c8c1SGroverkss   }
578506c8c1SGroverkss 
58bb901355SGroverkss   for (unsigned i = 0, e = rel.getNumInequalities(); i < e; ++i) {
591a0e67d7SRamkumar Ramachandra     ArrayRef<DynamicAPInt> ineq = rel.getInequality(i);
608506c8c1SGroverkss 
611a0e67d7SRamkumar Ramachandra     const DynamicAPInt &c = ineq.back();
628506c8c1SGroverkss 
631a0e67d7SRamkumar Ramachandra     SmallVector<DynamicAPInt, 8> newIneq = preMultiplyWithRow(ineq.drop_back());
64*266a5a9cSRamkumar Ramachandra     newIneq.emplace_back(c);
658506c8c1SGroverkss     result.addInequality(newIneq);
668506c8c1SGroverkss   }
678506c8c1SGroverkss 
688506c8c1SGroverkss   return result;
698506c8c1SGroverkss }
70