summaryrefslogtreecommitdiffstats
path: root/mlir/lib/Dialect/SDBM/SDBM.cpp
diff options
context:
space:
mode:
authorRiver Riddle <riverriddle@google.com>2019-08-19 11:00:47 -0700
committerA. Unique TensorFlower <gardener@tensorflow.org>2019-08-19 11:01:25 -0700
commitba0fa92524ce0aea2385858016bdb08bd941a10d (patch)
treee8b3d35a8647d2b751265391d1b85da1df1fd6bb /mlir/lib/Dialect/SDBM/SDBM.cpp
parent64abcd983ddcde4b9f27377fd718d04e88e35ab9 (diff)
downloadbcm5719-llvm-ba0fa92524ce0aea2385858016bdb08bd941a10d.tar.gz
bcm5719-llvm-ba0fa92524ce0aea2385858016bdb08bd941a10d.zip
NFC: Move LLVMIR, SDBM, and StandardOps to the Dialect/ directory.
PiperOrigin-RevId: 264193915
Diffstat (limited to 'mlir/lib/Dialect/SDBM/SDBM.cpp')
-rw-r--r--mlir/lib/Dialect/SDBM/SDBM.cpp561
1 files changed, 561 insertions, 0 deletions
diff --git a/mlir/lib/Dialect/SDBM/SDBM.cpp b/mlir/lib/Dialect/SDBM/SDBM.cpp
new file mode 100644
index 00000000000..5450a61b17b
--- /dev/null
+++ b/mlir/lib/Dialect/SDBM/SDBM.cpp
@@ -0,0 +1,561 @@
+//===- SDBM.cpp - MLIR SDBM implementation --------------------------------===//
+//
+// Copyright 2019 The MLIR Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+// =============================================================================
+//
+// A striped difference-bound matrix (SDBM) is a set in Z^N (or R^N) defined
+// as {(x_1, ... x_n) | f(x_1, ... x_n) >= 0} where f is an SDBM expression.
+//
+//===----------------------------------------------------------------------===//
+
+#include "mlir/Dialect/SDBM/SDBM.h"
+#include "mlir/Dialect/SDBM/SDBMExpr.h"
+
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/Support/FormatVariadic.h"
+#include "llvm/Support/raw_ostream.h"
+
+using namespace mlir;
+
+// Helper function for SDBM construction that collects information necessary to
+// start building an SDBM in one sweep. In particular, it records the largest
+// position of a dimension in `dim`, that of a symbol in `symbol` as well as
+// collects all unique stripe expressions in `stripes`. Uses SetVector to
+// ensure these expressions always have the same order.
+static void collectSDBMBuildInfo(SDBMExpr expr, int &dim, int &symbol,
+ llvm::SmallSetVector<SDBMExpr, 8> &stripes) {
+ struct Visitor : public SDBMVisitor<Visitor> {
+ void visitDim(SDBMDimExpr dimExpr) {
+ int p = dimExpr.getPosition();
+ if (p > maxDimPosition)
+ maxDimPosition = p;
+ }
+ void visitSymbol(SDBMSymbolExpr symbExpr) {
+ int p = symbExpr.getPosition();
+ if (p > maxSymbPosition)
+ maxSymbPosition = p;
+ }
+ void visitStripe(SDBMStripeExpr stripeExpr) { stripes.insert(stripeExpr); }
+
+ Visitor(llvm::SmallSetVector<SDBMExpr, 8> &stripes) : stripes(stripes) {}
+
+ int maxDimPosition = -1;
+ int maxSymbPosition = -1;
+ llvm::SmallSetVector<SDBMExpr, 8> &stripes;
+ };
+
+ Visitor visitor(stripes);
+ visitor.walkPostorder(expr);
+ dim = std::max(dim, visitor.maxDimPosition);
+ symbol = std::max(symbol, visitor.maxSymbPosition);
+}
+
+namespace {
+// Utility class for SDBMBuilder. Represents a value that can be inserted in
+// the SDB matrix that corresponds to "v0 - v1 + C <= 0", where v0 and v1 is
+// any combination of the positive and negative positions. Since multiple
+// variables can be declared equal to the same stripe expression, the
+// constraints on this expression must be reflected to all these variables. For
+// example, if
+// d0 = s0 # 42
+// d1 = s0 # 42
+// d2 = s1 # 2
+// d3 = s1 # 2
+// the constraint
+// s0 # 42 - s1 # 2 <= C
+// should be reflected in the DB matrix as
+// d0 - d2 <= C
+// d1 - d2 <= C
+// d0 - d3 <= C
+// d1 - d3 <= C
+// since the DB matrix has no knowledge of the transitive equality between d0,
+// d1 and s0 # 42 as well as between d2, d3 and s1 # 2. This knowledge can be
+// obtained by computing a transitive closure, which is impossible until the
+// DBM is actually built.
+struct SDBMBuilderResult {
+ // Positions in the matrix of the variables taken with the "+" sign in the
+ // difference expression, 0 if it is a constant rather than a variable.
+ llvm::SmallVector<unsigned, 2> positivePos;
+
+ // Positions in the matrix of the variables taken with the "-" sign in the
+ // difference expression, 0 if it is a constant rather than a variable.
+ llvm::SmallVector<unsigned, 2> negativePos;
+
+ // Constant value in the difference expression.
+ int64_t value = 0;
+};
+
+// Visitor for building an SDBM from SDBM expressions. After traversing an SDBM
+// expression, produces an update to the SDB matrix specifying the positions in
+// the matrix and the negated value that should be stored. Both the positive
+// and the negative positions may be lists of indices in cases where multiple
+// variables are equal to the same stripe expression. In such cases, the update
+// applies to the cross product of positions because elements involved in the
+// update are (transitively) equal and should have the same constraints, but we
+// may not have an explicit equality for them.
+struct SDBMBuilder : public SDBMVisitor<SDBMBuilder, SDBMBuilderResult> {
+public:
+ // A difference expression produces both the positive and the negative
+ // coordinate in the matrix, recursively traversing the LHS and the RHS. The
+ // value is the difference between values obtained from LHS and RHS.
+ SDBMBuilderResult visitDiff(SDBMDiffExpr diffExpr) {
+ auto lhs = visit(diffExpr.getLHS());
+ auto rhs = visit(diffExpr.getRHS());
+ assert(lhs.negativePos.size() == 1 && lhs.negativePos[0] == 0 &&
+ "unexpected negative expression in a difference expression");
+ assert(rhs.negativePos.size() == 1 && lhs.negativePos[0] == 0 &&
+ "unexpected negative expression in a difference expression");
+
+ SDBMBuilderResult result;
+ result.positivePos = lhs.positivePos;
+ result.negativePos = rhs.positivePos;
+ result.value = lhs.value - rhs.value;
+ return result;
+ }
+
+ // An input expression is always taken with the "+" sign and therefore
+ // produces a positive coordinate keeping the negative coordinate zero for an
+ // eventual constant.
+ SDBMBuilderResult visitInput(SDBMInputExpr expr) {
+ SDBMBuilderResult r;
+ r.positivePos.push_back(linearPosition(expr));
+ r.negativePos.push_back(0);
+ return r;
+ }
+
+ // A stripe expression is always equal to one or more variables, which may be
+ // temporaries, and appears with a "+" sign in the SDBM expression tree. Take
+ // the positions of the corresponding variables as positive coordinates.
+ SDBMBuilderResult visitStripe(SDBMStripeExpr expr) {
+ SDBMBuilderResult r;
+ assert(pointExprToStripe.count(expr));
+ r.positivePos = pointExprToStripe[expr];
+ r.negativePos.push_back(0);
+ return r;
+ }
+
+ // A constant expression has both coordinates at zero.
+ SDBMBuilderResult visitConstant(SDBMConstantExpr expr) {
+ SDBMBuilderResult r;
+ r.positivePos.push_back(0);
+ r.negativePos.push_back(0);
+ r.value = expr.getValue();
+ return r;
+ }
+
+ // A negation expression swaps the positive and the negative coordinates
+ // and also negates the constant value.
+ SDBMBuilderResult visitNeg(SDBMNegExpr expr) {
+ SDBMBuilderResult result = visit(expr.getVar());
+ std::swap(result.positivePos, result.negativePos);
+ result.value = -result.value;
+ return result;
+ }
+
+ // The RHS of a sum expression must be a constant and therefore must have both
+ // positive and negative coordinates at zero. Take the sum of the values
+ // between LHS and RHS and keep LHS coordinates.
+ SDBMBuilderResult visitSum(SDBMSumExpr expr) {
+ auto lhs = visit(expr.getLHS());
+ auto rhs = visit(expr.getRHS());
+ for (auto pos : rhs.negativePos) {
+ (void)pos;
+ assert(pos == 0 && "unexpected variable on the RHS of SDBM sum");
+ }
+ for (auto pos : rhs.positivePos) {
+ (void)pos;
+ assert(pos == 0 && "unexpected variable on the RHS of SDBM sum");
+ }
+
+ lhs.value += rhs.value;
+ return lhs;
+ }
+
+ SDBMBuilder(llvm::DenseMap<SDBMExpr, llvm::SmallVector<unsigned, 2>>
+ &pointExprToStripe,
+ llvm::function_ref<unsigned(SDBMInputExpr)> callback)
+ : pointExprToStripe(pointExprToStripe), linearPosition(callback) {}
+
+ llvm::DenseMap<SDBMExpr, llvm::SmallVector<unsigned, 2>> &pointExprToStripe;
+ llvm::function_ref<unsigned(SDBMInputExpr)> linearPosition;
+};
+} // namespace
+
+SDBM SDBM::get(ArrayRef<SDBMExpr> inequalities, ArrayRef<SDBMExpr> equalities) {
+ SDBM result;
+
+ // TODO(zinenko): consider detecting equalities in the list of inequalities.
+ // This is potentially expensive and requires to
+ // - create a list of negated inequalities (may allocate under lock);
+ // - perform a pairwise comparison of direct and negated inequalities;
+ // - copy the lists of equalities and inequalities, and move entries between
+ // them;
+ // only for the purpose of sparing a temporary variable in cases where an
+ // implicit equality between a variable and a stripe expression is present in
+ // the input.
+
+ // Do the first sweep over (in)equalities to collect the information necessary
+ // to allocate the SDB matrix (number of dimensions, symbol and temporary
+ // variables required for stripe expressions).
+ llvm::SmallSetVector<SDBMExpr, 8> stripes;
+ int maxDim = -1;
+ int maxSymbol = -1;
+ for (auto expr : inequalities)
+ collectSDBMBuildInfo(expr, maxDim, maxSymbol, stripes);
+ for (auto expr : equalities)
+ collectSDBMBuildInfo(expr, maxDim, maxSymbol, stripes);
+ // Indexing of dimensions starts with 0, obtain the number of dimensions by
+ // incrementing the maximal position of the dimension seen in expressions.
+ result.numDims = maxDim + 1;
+ result.numSymbols = maxSymbol + 1;
+ result.numTemporaries = 0;
+
+ // Helper function that returns the position of the variable represented by
+ // an SDBM input expression.
+ auto linearPosition = [result](SDBMInputExpr expr) {
+ if (expr.isa<SDBMDimExpr>())
+ return result.getDimPosition(expr.getPosition());
+ return result.getSymbolPosition(expr.getPosition());
+ };
+
+ // Check if some stripe expressions are equal to another variable. In
+ // particular, look for the equalities of the form
+ // d0 - stripe-expression = 0, or
+ // stripe-expression - d0 = 0.
+ // There may be multiple variables that are equal to the same stripe
+ // expression. Keep track of those in pointExprToStripe.
+ // There may also be multiple stripe expressions equal to the same variable.
+ // Introduce a temporary variable for each of those.
+ llvm::DenseMap<SDBMExpr, llvm::SmallVector<unsigned, 2>> pointExprToStripe;
+ unsigned numTemporaries = 0;
+
+ auto updateStripePointMaps = [&numTemporaries, &result, &pointExprToStripe,
+ linearPosition](SDBMInputExpr input,
+ SDBMExpr expr) {
+ unsigned position = linearPosition(input);
+ if (result.stripeToPoint.count(position) &&
+ result.stripeToPoint[position] != expr) {
+ position = result.getNumVariables() + numTemporaries++;
+ }
+ pointExprToStripe[expr].push_back(position);
+ result.stripeToPoint.insert(std::make_pair(position, expr));
+ };
+
+ for (auto eq : equalities) {
+ auto diffExpr = eq.dyn_cast<SDBMDiffExpr>();
+ if (!diffExpr)
+ continue;
+
+ auto lhs = diffExpr.getLHS();
+ auto rhs = diffExpr.getRHS();
+ auto lhsInput = lhs.dyn_cast<SDBMInputExpr>();
+ auto rhsInput = rhs.dyn_cast<SDBMInputExpr>();
+
+ if (lhsInput && stripes.count(rhs))
+ updateStripePointMaps(lhsInput, rhs);
+ if (rhsInput && stripes.count(lhs))
+ updateStripePointMaps(rhsInput, lhs);
+ }
+
+ // Assign the remaining stripe expressions to temporary variables. These
+ // expressions are the ones that could not be associated with an existing
+ // variable in the previous step.
+ for (auto expr : stripes) {
+ if (pointExprToStripe.count(expr))
+ continue;
+ unsigned position = result.getNumVariables() + numTemporaries++;
+ pointExprToStripe[expr].push_back(position);
+ result.stripeToPoint.insert(std::make_pair(position, expr));
+ }
+
+ // Create the DBM matrix, initialized to infinity values for the least tight
+ // possible bound (x - y <= infinity is always true).
+ result.numTemporaries = numTemporaries;
+ result.matrix.resize(result.getNumVariables() * result.getNumVariables(),
+ IntInfty::infinity());
+
+ SDBMBuilder builder(pointExprToStripe, linearPosition);
+
+ // Only keep the tightest constraint. Since we transform everything into
+ // less-than-or-equals-to inequalities, keep the smallest constant. For
+ // example, if we have d0 - d1 <= 42 and d0 - d1 <= 2, we keep the latter.
+ // Note that the input expressions are in the shape of d0 - d1 + -42 <= 0
+ // so we negate the value before storing it.
+ // In case where the positive and the negative positions are equal, the
+ // corresponding expression has the form d0 - d0 + -42 <= 0. If the constant
+ // value is positive, the set defined by SDBM is trivially empty. We store
+ // this value anyway and continue processing to maintain the correspondence
+ // between the matrix form and the list-of-SDBMExpr form.
+ // TODO(zinenko): we may want to reconsider this once we have canonicalization
+ // or simplification in place
+ auto updateMatrix = [](SDBM &sdbm, const SDBMBuilderResult &r) {
+ for (auto positivePos : r.positivePos) {
+ for (auto negativePos : r.negativePos) {
+ auto &m = sdbm.at(negativePos, positivePos);
+ m = m < -r.value ? m : -r.value;
+ }
+ }
+ };
+
+ // Do the second sweep on (in)equalities, updating the SDB matrix to reflect
+ // the constraints.
+ for (auto ineq : inequalities)
+ updateMatrix(result, builder.visit(ineq));
+
+ // An equality f(x) = 0 is represented as a pair of inequalities {f(x) >= 0;
+ // f(x) <= 0} or, alternatively, {-f(x) <= 0 and f(x) <= 0}.
+ for (auto eq : equalities) {
+ updateMatrix(result, builder.visit(eq));
+ updateMatrix(result, builder.visit(-eq));
+ }
+
+ // Add the inequalities induced by stripe equalities.
+ // t = x # C => t <= x <= t + C - 1
+ // which is equivalent to
+ // {t - x <= 0;
+ // x - t - (C - 1) <= 0}.
+ for (const auto &pair : result.stripeToPoint) {
+ auto stripe = pair.second.cast<SDBMStripeExpr>();
+ SDBMBuilderResult update = builder.visit(stripe.getVar());
+ assert(update.negativePos.size() == 1 && update.negativePos[0] == 0 &&
+ "unexpected negated variable in stripe expression");
+ assert(update.value == 0 &&
+ "unexpected non-zero value in stripe expression");
+ update.negativePos.clear();
+ update.negativePos.push_back(pair.first);
+ update.value = -(stripe.getStripeFactor().getValue() - 1);
+ updateMatrix(result, update);
+
+ std::swap(update.negativePos, update.positivePos);
+ update.value = 0;
+ updateMatrix(result, update);
+ }
+
+ return result;
+}
+
+// Given a row and a column position in the square DBM, insert one equality
+// or up to two inequalities that correspond the entries (col, row) and (row,
+// col) in the DBM. `rowExpr` and `colExpr` contain the expressions such that
+// colExpr - rowExpr <= V where V is the value at (row, col) in the DBM.
+// If one of the expressions is derived from another using a stripe operation,
+// check if the inequalities induced by the stripe operation subsume the
+// inequalities defined in the DBM and if so, elide these inequalities.
+void SDBM::convertDBMElement(unsigned row, unsigned col,
+ SDBMPositiveExpr rowExpr, SDBMPositiveExpr colExpr,
+ SmallVectorImpl<SDBMExpr> &inequalities,
+ SmallVectorImpl<SDBMExpr> &equalities) {
+ using ops_assertions::operator+;
+ using ops_assertions::operator-;
+
+ auto diffIJValue = at(col, row);
+ auto diffJIValue = at(row, col);
+
+ // If symmetric entries are opposite, the corresponding expressions are equal.
+ if (diffIJValue.isFinite() &&
+ diffIJValue.getValue() == -diffJIValue.getValue()) {
+ equalities.push_back(rowExpr - colExpr - diffIJValue.getValue());
+ return;
+ }
+
+ // Given an inequality x0 - x1 <= A, check if x0 is a stripe variable derived
+ // from x1: x0 = x1 # B. If so, it would imply the constraints
+ // x0 <= x1 <= x0 + (B - 1) <=> x0 - x1 <= 0 and x1 - x0 <= (B - 1).
+ // Therefore, if A >= 0, this inequality is subsumed by that implied
+ // by the stripe equality and thus can be elided.
+ // Similarly, check if x1 is a stripe variable derived from x0: x1 = x0 # C.
+ // If so, it would imply the constraints x1 <= x0 <= x1 + (C - 1) <=>
+ // <=> x1 - x0 <= 0 and x0 - x1 <= (C - 1). Therefore, if A >= (C - 1), this
+ // inequality can be elided.
+ //
+ // Note: x0 and x1 may be a stripe expressions themselves, we rely on stripe
+ // expressions being stored without temporaries on the RHS and being passed
+ // into this function as is.
+ auto canElide = [this](unsigned x0, unsigned x1, SDBMExpr x0Expr,
+ SDBMExpr x1Expr, int64_t value) {
+ if (stripeToPoint.count(x0)) {
+ auto stripe = stripeToPoint[x0].cast<SDBMStripeExpr>();
+ SDBMPositiveExpr var = stripe.getVar();
+ if (x1Expr == var && value >= 0)
+ return true;
+ }
+ if (stripeToPoint.count(x1)) {
+ auto stripe = stripeToPoint[x1].cast<SDBMStripeExpr>();
+ SDBMPositiveExpr var = stripe.getVar();
+ if (x0Expr == var && value >= stripe.getStripeFactor().getValue() - 1)
+ return true;
+ }
+ return false;
+ };
+
+ // Check row - col.
+ if (diffIJValue.isFinite() &&
+ !canElide(row, col, rowExpr, colExpr, diffIJValue.getValue())) {
+ inequalities.push_back(rowExpr - colExpr - diffIJValue.getValue());
+ }
+ // Check col - row.
+ if (diffJIValue.isFinite() &&
+ !canElide(col, row, colExpr, rowExpr, diffJIValue.getValue())) {
+ inequalities.push_back(colExpr - rowExpr - diffJIValue.getValue());
+ }
+}
+
+// The values on the main diagonal correspond to the upper bound on the
+// difference between a variable and itself: d0 - d0 <= C, or alternatively
+// to -C <= 0. Only construct the inequalities when C is negative, which
+// are trivially false but necessary for the returned system of inequalities
+// to indicate that the set it defines is empty.
+void SDBM::convertDBMDiagonalElement(unsigned pos, SDBMPositiveExpr expr,
+ SmallVectorImpl<SDBMExpr> &inequalities) {
+ auto selfDifference = at(pos, pos);
+ if (selfDifference.isFinite() && selfDifference < 0) {
+ auto selfDifferenceValueExpr =
+ SDBMConstantExpr::get(expr.getDialect(), -selfDifference.getValue());
+ inequalities.push_back(selfDifferenceValueExpr);
+ }
+}
+
+void SDBM::getSDBMExpressions(SDBMDialect *dialect,
+ SmallVectorImpl<SDBMExpr> &inequalities,
+ SmallVectorImpl<SDBMExpr> &equalities) {
+ using ops_assertions::operator-;
+ using ops_assertions::operator+;
+
+ // Helper function that creates an SDBMInputExpr given the linearized position
+ // of variable in the DBM.
+ auto getInput = [dialect, this](unsigned matrixPos) -> SDBMInputExpr {
+ if (matrixPos < numDims)
+ return SDBMDimExpr::get(dialect, matrixPos);
+ return SDBMSymbolExpr::get(dialect, matrixPos - numDims);
+ };
+
+ // The top-left value corresponds to inequality 0 <= C. If C is negative, the
+ // set defined by SDBM is trivially empty and we add the constraint -C <= 0 to
+ // the list of inequalities. Otherwise, the constraint is trivially true and
+ // we ignore it.
+ auto difference = at(0, 0);
+ if (difference.isFinite() && difference < 0) {
+ inequalities.push_back(
+ SDBMConstantExpr::get(dialect, -difference.getValue()));
+ }
+
+ // Traverse the segment of the matrix that involves non-temporary variables.
+ unsigned numTrueVariables = numDims + numSymbols;
+ for (unsigned i = 0; i < numTrueVariables; ++i) {
+ // The first row and column represent numerical upper and lower bound on
+ // each variable. Transform them into inequalities if they are finite.
+ auto upperBound = at(0, 1 + i);
+ auto lowerBound = at(1 + i, 0);
+ auto inputExpr = getInput(i);
+ if (upperBound.isFinite() &&
+ upperBound.getValue() == -lowerBound.getValue()) {
+ equalities.push_back(inputExpr - upperBound.getValue());
+ } else if (upperBound.isFinite()) {
+ inequalities.push_back(inputExpr - upperBound.getValue());
+ } else if (lowerBound.isFinite()) {
+ inequalities.push_back(-inputExpr - lowerBound.getValue());
+ }
+
+ // Introduce trivially false inequalities if required by diagonal elements.
+ convertDBMDiagonalElement(1 + i, inputExpr, inequalities);
+
+ // Introduce equalities or inequalities between non-temporary variables.
+ for (unsigned j = 0; j < i; ++j) {
+ convertDBMElement(1 + i, 1 + j, getInput(i), getInput(j), inequalities,
+ equalities);
+ }
+ }
+
+ // Add equalities for stripe expressions that define non-temporary
+ // variables. Temporary variables will be substituted into their uses and
+ // should not appear in the resulting equalities.
+ for (const auto &stripePair : stripeToPoint) {
+ unsigned position = stripePair.first;
+ if (position < 1 + numTrueVariables) {
+ equalities.push_back(getInput(position - 1) - stripePair.second);
+ }
+ }
+
+ // Add equalities / inequalities involving temporaries by replacing the
+ // temporaries with stripe expressions that define them.
+ for (unsigned i = 1 + numTrueVariables, e = getNumVariables(); i < e; ++i) {
+ // Mixed constraints involving one temporary (j) and one non-temporary (i)
+ // variable.
+ for (unsigned j = 0; j < numTrueVariables; ++j) {
+ convertDBMElement(i, 1 + j, stripeToPoint[i].cast<SDBMStripeExpr>(),
+ getInput(j), inequalities, equalities);
+ }
+
+ // Constraints involving only temporary variables.
+ for (unsigned j = 1 + numTrueVariables; j < i; ++j) {
+ convertDBMElement(i, j, stripeToPoint[i].cast<SDBMStripeExpr>(),
+ stripeToPoint[j].cast<SDBMStripeExpr>(), inequalities,
+ equalities);
+ }
+
+ // Introduce trivially false inequalities if required by diagonal elements.
+ convertDBMDiagonalElement(i, stripeToPoint[i].cast<SDBMStripeExpr>(),
+ inequalities);
+ }
+}
+
+void SDBM::print(llvm::raw_ostream &os) {
+ unsigned numVariables = getNumVariables();
+
+ // Helper function that prints the name of the variable given its linearized
+ // position in the DBM.
+ auto getVarName = [this](unsigned matrixPos) -> std::string {
+ if (matrixPos == 0)
+ return "cst";
+ matrixPos -= 1;
+ if (matrixPos < numDims)
+ return llvm::formatv("d{0}", matrixPos);
+ matrixPos -= numDims;
+ if (matrixPos < numSymbols)
+ return llvm::formatv("s{0}", matrixPos);
+ matrixPos -= numSymbols;
+ return llvm::formatv("t{0}", matrixPos);
+ };
+
+ // Header row.
+ os << " cst";
+ for (unsigned i = 1; i < numVariables; ++i) {
+ os << llvm::formatv(" {0,4}", getVarName(i));
+ }
+ os << '\n';
+
+ // Data rows.
+ for (unsigned i = 0; i < numVariables; ++i) {
+ os << llvm::formatv("{0,-4}", getVarName(i));
+ for (unsigned j = 0; j < numVariables; ++j) {
+ IntInfty value = operator()(i, j);
+ if (!value.isFinite())
+ os << " inf";
+ else
+ os << llvm::formatv(" {0,4}", value.getValue());
+ }
+ os << '\n';
+ }
+
+ // Explanation of temporaries.
+ for (const auto &pair : stripeToPoint) {
+ os << getVarName(pair.first) << " = ";
+ pair.second.print(os);
+ os << '\n';
+ }
+}
+
+void SDBM::dump() { print(llvm::errs()); }
OpenPOWER on IntegriCloud