//===- LinearTransform.cpp - MLIR LinearTransform Class -------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// #include "mlir/Analysis/Presburger/LinearTransform.h" #include "mlir/Analysis/Presburger/IntegerRelation.h" #include "mlir/Analysis/Presburger/Matrix.h" #include using namespace mlir; using namespace presburger; LinearTransform::LinearTransform(IntMatrix &&oMatrix) : matrix(oMatrix) {} LinearTransform::LinearTransform(const IntMatrix &oMatrix) : matrix(oMatrix) {} std::pair LinearTransform::makeTransformToColumnEchelon(const IntMatrix &m) { // Compute the hermite normal form of m. This, is by definition, is in column // echelon form. auto [h, u] = m.computeHermiteNormalForm(); // Since the matrix is in column ecehlon form, a zero column means the rest of // the columns are zero. Thus, once we find a zero column, we can stop. unsigned col, e; for (col = 0, e = m.getNumColumns(); col < e; ++col) { bool zeroCol = true; for (unsigned row = 0, f = m.getNumRows(); row < f; ++row) { if (h(row, col) != 0) { zeroCol = false; break; } } if (zeroCol) break; } return {col, LinearTransform(std::move(u))}; } IntegerRelation LinearTransform::applyTo(const IntegerRelation &rel) const { IntegerRelation result(rel.getSpace()); for (unsigned i = 0, e = rel.getNumEqualities(); i < e; ++i) { ArrayRef eq = rel.getEquality(i); const DynamicAPInt &c = eq.back(); SmallVector newEq = preMultiplyWithRow(eq.drop_back()); newEq.emplace_back(c); result.addEquality(newEq); } for (unsigned i = 0, e = rel.getNumInequalities(); i < e; ++i) { ArrayRef ineq = rel.getInequality(i); const DynamicAPInt &c = ineq.back(); SmallVector newIneq = preMultiplyWithRow(ineq.drop_back()); newIneq.emplace_back(c); result.addInequality(newIneq); } return result; }