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