You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
202 lines
5.7 KiB
202 lines
5.7 KiB
//===- sdbm-api-test.cpp - Tests for SDBM expression APIs -----------------===//
|
|
//
|
|
// 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
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
// RUN: mlir-sdbm-api-test | FileCheck %s
|
|
|
|
#include "mlir/Dialect/SDBM/SDBM.h"
|
|
#include "mlir/Dialect/SDBM/SDBMDialect.h"
|
|
#include "mlir/Dialect/SDBM/SDBMExpr.h"
|
|
#include "mlir/IR/MLIRContext.h"
|
|
|
|
#include "llvm/Support/raw_ostream.h"
|
|
|
|
#include "APITest.h"
|
|
|
|
using namespace mlir;
|
|
|
|
|
|
static MLIRContext *ctx() {
|
|
static thread_local MLIRContext context;
|
|
static thread_local bool once =
|
|
(context.getOrLoadDialect<SDBMDialect>(), true);
|
|
(void)once;
|
|
return &context;
|
|
}
|
|
|
|
static SDBMDialect *dialect() {
|
|
static thread_local SDBMDialect *d = nullptr;
|
|
if (!d) {
|
|
d = ctx()->getOrLoadDialect<SDBMDialect>();
|
|
}
|
|
return d;
|
|
}
|
|
|
|
static SDBMExpr dim(unsigned pos) { return SDBMDimExpr::get(dialect(), pos); }
|
|
|
|
static SDBMExpr symb(unsigned pos) {
|
|
return SDBMSymbolExpr::get(dialect(), pos);
|
|
}
|
|
|
|
namespace {
|
|
|
|
using namespace mlir::ops_assertions;
|
|
|
|
TEST_FUNC(SDBM_SingleConstraint) {
|
|
// Build an SDBM defined by
|
|
// d0 - 3 <= 0 <=> d0 <= 3.
|
|
auto sdbm = SDBM::get(dim(0) - 3, llvm::None);
|
|
|
|
// CHECK: cst d0
|
|
// CHECK-NEXT: cst inf 3
|
|
// CHECK-NEXT: d0 inf inf
|
|
sdbm.print(llvm::outs());
|
|
}
|
|
|
|
TEST_FUNC(SDBM_Equality) {
|
|
// Build an SDBM defined by
|
|
//
|
|
// d0 - d1 - 3 = 0
|
|
// <=> {d0 - d1 - 3 <= 0 and d0 - d1 - 3 >= 0}
|
|
// <=> {d0 - d1 <= 3 and d1 - d0 <= -3}.
|
|
auto sdbm = SDBM::get(llvm::None, dim(0) - dim(1) - 3);
|
|
|
|
// CHECK: cst d0 d1
|
|
// CHECK-NEXT: cst inf inf inf
|
|
// CHECK-NEXT: d0 inf inf -3
|
|
// CHECK-NEXT: d1 inf 3 inf
|
|
sdbm.print(llvm::outs());
|
|
}
|
|
|
|
TEST_FUNC(SDBM_TrivialSimplification) {
|
|
// Build an SDBM defined by
|
|
//
|
|
// d0 - 3 <= 0 <=> d0 <= 3
|
|
// d0 - 5 <= 0 <=> d0 <= 5
|
|
//
|
|
// which should get simplified on construction to only the former.
|
|
auto sdbm = SDBM::get({dim(0) - 3, dim(0) - 5}, llvm::None);
|
|
|
|
// CHECK: cst d0
|
|
// CHECK-NEXT: cst inf 3
|
|
// CHECK-NEXT: d0 inf inf
|
|
sdbm.print(llvm::outs());
|
|
}
|
|
|
|
TEST_FUNC(SDBM_StripeInducedIneqs) {
|
|
// Build an SDBM defined by d1 = d0 # 3, which induces the constraints
|
|
//
|
|
// d1 - d0 <= 0
|
|
// d0 - d1 <= 3 - 1 = 2
|
|
auto sdbm = SDBM::get(llvm::None, dim(1) - stripe(dim(0), 3));
|
|
|
|
// CHECK: cst d0 d1
|
|
// CHECK-NEXT: cst inf inf inf
|
|
// CHECK-NEXT: d0 inf inf 0
|
|
// CHECK-NEXT: d1 inf 2 0
|
|
// CHECK-NEXT: d1 = d0 # 3
|
|
sdbm.print(llvm::outs());
|
|
}
|
|
|
|
TEST_FUNC(SDBM_StripeTemporaries) {
|
|
// Build an SDBM defined by d0 # 3 <= 0, which creates a temporary
|
|
// t0 = d0 # 3 leading to a constraint t0 <= 0 and the stripe-induced
|
|
// constraints
|
|
//
|
|
// t0 - d0 <= 0
|
|
// d0 - t0 <= 3 - 1 = 2
|
|
auto sdbm = SDBM::get(stripe(dim(0), 3), llvm::None);
|
|
|
|
// CHECK: cst d0 t0
|
|
// CHECK-NEXT: cst inf inf 0
|
|
// CHECK-NEXT: d0 inf inf 0
|
|
// CHECK-NEXT: t0 inf 2 inf
|
|
// CHECK-NEXT: t0 = d0 # 3
|
|
sdbm.print(llvm::outs());
|
|
}
|
|
|
|
TEST_FUNC(SDBM_ElideInducedInequalities) {
|
|
// Build an SDBM defined by a single stripe equality d0 = s0 # 3 and make sure
|
|
// the induced inequalities are not present after converting the SDBM back
|
|
// into lists of expressions.
|
|
auto sdbm = SDBM::get(llvm::None, {dim(0) - stripe(symb(0), 3)});
|
|
|
|
SmallVector<SDBMExpr, 4> eqs, ineqs;
|
|
sdbm.getSDBMExpressions(dialect(), ineqs, eqs);
|
|
// CHECK-EMPTY:
|
|
for (auto ineq : ineqs)
|
|
ineq.print(llvm::outs() << '\n');
|
|
llvm::outs() << "\n";
|
|
|
|
// CHECK: d0 - s0 # 3
|
|
// CHECK-EMPTY:
|
|
for (auto eq : eqs)
|
|
eq.print(llvm::outs() << '\n');
|
|
llvm::outs() << "\n\n";
|
|
}
|
|
|
|
TEST_FUNC(SDBM_StripeTightening) {
|
|
// Build an SDBM defined by
|
|
//
|
|
// d0 = s0 # 3 # 5
|
|
// s0 # 3 # 5 - d1 + 42 = 0
|
|
// s0 # 3 - d0 <= 2
|
|
//
|
|
// where the last inequality is tighter than that induced by the first stripe
|
|
// equality (s0 # 3 - d0 <= 5 - 1 = 4). Check that the conversion from SDBM
|
|
// back to the lists of constraints conserves both the stripe equality and the
|
|
// tighter inequality.
|
|
auto s = stripe(stripe(symb(0), 3), 5);
|
|
auto tight = stripe(symb(0), 3) - dim(0) - 2;
|
|
auto sdbm = SDBM::get({tight}, {s - dim(0), s - dim(1) + 42});
|
|
|
|
SmallVector<SDBMExpr, 4> eqs, ineqs;
|
|
sdbm.getSDBMExpressions(dialect(), ineqs, eqs);
|
|
// CHECK: s0 # 3 + -2 - d0
|
|
// CHECK-EMPTY:
|
|
for (auto ineq : ineqs)
|
|
ineq.print(llvm::outs() << '\n');
|
|
llvm::outs() << "\n";
|
|
|
|
// CHECK-DAG: d1 + -42 - d0
|
|
// CHECK-DAG: d0 - s0 # 3 # 5
|
|
for (auto eq : eqs)
|
|
eq.print(llvm::outs() << '\n');
|
|
llvm::outs() << "\n\n";
|
|
}
|
|
|
|
TEST_FUNC(SDBM_StripeTransitive) {
|
|
// Build an SDBM defined by
|
|
//
|
|
// d0 = d1 # 3
|
|
// d0 = d2 # 7
|
|
//
|
|
// where the same dimension is declared equal to two stripe expressions over
|
|
// different variables. This is practically handled by introducing a
|
|
// temporary variable for the second stripe expression and adding an equality
|
|
// constraint between this variable and the original dimension variable.
|
|
auto sdbm = SDBM::get(
|
|
llvm::None, {stripe(dim(1), 3) - dim(0), stripe(dim(2), 7) - dim(0)});
|
|
|
|
// CHECK: cst d0 d1 d2 t0
|
|
// CHECK-NEXT: cst inf inf inf inf inf
|
|
// CHECK-NEXT: d0 inf 0 2 inf 0
|
|
// CHECK-NEXT: d1 inf 0 inf inf inf
|
|
// CHECK-NEXT: d2 inf inf inf inf 0
|
|
// CHECK-NEXT: t0 inf 0 inf 6 inf
|
|
// CHECK-NEXT: t0 = d2 # 7
|
|
// CHECK-NEXT: d0 = d1 # 3
|
|
sdbm.print(llvm::outs());
|
|
}
|
|
|
|
} // end namespace
|
|
|
|
int main() {
|
|
RUN_TESTS();
|
|
return 0;
|
|
}
|