[mlir][EDSC] Refactor dependencies involving EDSCs.

Summary: This diff removes the dependency of LinalgOps and VectorOps on EDSCs.

Reviewers: jpienaar, ftynse

Reviewed By: ftynse

Subscribers: merge_guards_bot, mgorny, mehdi_amini, rriddle, burmako, shauheen, antiagainst, csigg, arpith-jacob, mgester, lucyrfox, herhut, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D72481
This commit is contained in:
Nicolas Vasilache 2020-01-15 09:28:12 -05:00
parent 441410be47
commit 89b395fe79
20 changed files with 291 additions and 208 deletions

View File

@ -24,6 +24,64 @@ namespace mlir {
class BlockArgument;
namespace edsc {
/// A LoopRangeBuilder is a generic NestedBuilder for loop.for operations.
/// More specifically it is meant to be used as a temporary object for
/// representing any nested MLIR construct that is "related to" an mlir::Value
/// (for now an induction variable).
class LoopRangeBuilder : public NestedBuilder {
public:
/// Constructs a new loop.for and captures the associated induction
/// variable. A ValueHandle pointer is passed as the first argument and is the
/// *only* way to capture the loop induction variable.
LoopRangeBuilder(ValueHandle *iv, ValueHandle range);
LoopRangeBuilder(ValueHandle *iv, Value range);
LoopRangeBuilder(ValueHandle *iv, SubViewOp::Range range);
LoopRangeBuilder(const LoopRangeBuilder &) = delete;
LoopRangeBuilder(LoopRangeBuilder &&) = default;
LoopRangeBuilder &operator=(const LoopRangeBuilder &) = delete;
LoopRangeBuilder &operator=(LoopRangeBuilder &&) = default;
/// The only purpose of this operator is to serve as a sequence point so that
/// the evaluation of `fun` (which build IR snippets in a scoped fashion) is
/// scoped within a LoopRangeBuilder.
ValueHandle operator()(std::function<void(void)> fun = nullptr);
};
/// Helper class to sugar building loop.for loop nests from ranges.
/// This is similar to edsc::AffineLoopNestBuilder except it works on ranges
/// directly. In the current implementation it produces loop.for operations.
class LoopNestRangeBuilder {
public:
LoopNestRangeBuilder(ArrayRef<edsc::ValueHandle *> ivs,
ArrayRef<edsc::ValueHandle> ranges);
LoopNestRangeBuilder(ArrayRef<edsc::ValueHandle *> ivs,
ArrayRef<Value> ranges);
LoopNestRangeBuilder(ArrayRef<edsc::ValueHandle *> ivs,
ArrayRef<SubViewOp::Range> ranges);
edsc::ValueHandle operator()(std::function<void(void)> fun = nullptr);
private:
SmallVector<LoopRangeBuilder, 4> loops;
};
/// Helper template class for building loop.for and affine.loop nests from
/// ranges.
template <typename LoopTy> class GenericLoopNestRangeBuilder {
public:
GenericLoopNestRangeBuilder(ArrayRef<edsc::ValueHandle *> ivs,
ArrayRef<Value> ranges);
void operator()(std::function<void(void)> fun = nullptr) { (*builder)(fun); }
private:
typedef typename std::conditional<std::is_same<LoopTy, AffineForOp>::value,
AffineLoopNestBuilder,
LoopNestRangeBuilder>::type BuilderType;
std::unique_ptr<BuilderType> builder;
};
enum class IterType { Parallel, Reduction };
inline StringRef toString(IterType t) {

View File

@ -12,7 +12,6 @@
#include "mlir/Dialect/Linalg/IR/LinalgOps.h"
#include "mlir/Dialect/LoopOps/LoopOps.h"
#include "mlir/Dialect/StandardOps/Ops.h"
#include "mlir/EDSC/Helpers.h"
#include "llvm/ADT/SetVector.h"
@ -21,67 +20,6 @@ class AffineExpr;
class AffineMap;
class OperationFolder;
namespace edsc {
/// A LoopRangeBuilder is a generic NestedBuilder for loop.for operations.
/// More specifically it is meant to be used as a temporary object for
/// representing any nested MLIR construct that is "related to" an mlir::Value
/// (for now an induction variable).
class LoopRangeBuilder : public NestedBuilder {
public:
/// Constructs a new loop.for and captures the associated induction
/// variable. A ValueHandle pointer is passed as the first argument and is the
/// *only* way to capture the loop induction variable.
LoopRangeBuilder(ValueHandle *iv, ValueHandle range);
LoopRangeBuilder(ValueHandle *iv, Value range);
LoopRangeBuilder(ValueHandle *iv, SubViewOp::Range range);
LoopRangeBuilder(const LoopRangeBuilder &) = delete;
LoopRangeBuilder(LoopRangeBuilder &&) = default;
LoopRangeBuilder &operator=(const LoopRangeBuilder &) = delete;
LoopRangeBuilder &operator=(LoopRangeBuilder &&) = default;
/// The only purpose of this operator is to serve as a sequence point so that
/// the evaluation of `fun` (which build IR snippets in a scoped fashion) is
/// scoped within a LoopRangeBuilder.
ValueHandle operator()(std::function<void(void)> fun = nullptr);
};
/// Helper class to sugar building loop.for loop nests from ranges.
/// This is similar to edsc::AffineLoopNestBuilder except it works on ranges
/// directly. In the current implementation it produces loop.for operations.
class LoopNestRangeBuilder {
public:
LoopNestRangeBuilder(ArrayRef<edsc::ValueHandle *> ivs,
ArrayRef<edsc::ValueHandle> ranges);
LoopNestRangeBuilder(ArrayRef<edsc::ValueHandle *> ivs,
ArrayRef<Value> ranges);
LoopNestRangeBuilder(ArrayRef<edsc::ValueHandle *> ivs,
ArrayRef<SubViewOp::Range> ranges);
edsc::ValueHandle operator()(std::function<void(void)> fun = nullptr);
private:
SmallVector<LoopRangeBuilder, 4> loops;
};
/// Helper template class for building loop.for and affine.loop nests from
/// ranges.
template <typename LoopTy> class GenericLoopNestRangeBuilder {
public:
GenericLoopNestRangeBuilder(ArrayRef<edsc::ValueHandle *> ivs,
ArrayRef<Value> ranges);
void operator()(std::function<void(void)> fun = nullptr) { (*builder)(fun); }
private:
typedef typename std::conditional<std::is_same<LoopTy, AffineForOp>::value,
AffineLoopNestBuilder,
LoopNestRangeBuilder>::type BuilderType;
std::unique_ptr<BuilderType> builder;
};
} // namespace edsc
namespace linalg {
class LinalgDependenceGraph;
@ -117,12 +55,13 @@ Optional<FusionInfo> fuseProducerOf(OpBuilder &b, LinalgOp consumer,
/// the inverse, concatenated loopToOperandRangeMaps to this list allows the
/// derivation of loop ranges for any linalgOp.
template <typename ConcreteOp>
SmallVector<Value, 8> getViewSizes(ConcreteOp linalgOp) {
SmallVector<Value, 8> getViewSizes(OpBuilder &builder, ConcreteOp linalgOp) {
auto loc = linalgOp.getLoc();
SmallVector<Value, 8> res;
for (auto v : linalgOp.getInputsAndOutputBuffers()) {
MemRefType t = v.getType().template cast<MemRefType>();
for (unsigned i = 0; i < t.getRank(); ++i)
res.push_back(edsc::intrinsics::dim(v, i));
res.push_back(builder.create<DimOp>(loc, v, i));
}
return res;
}

View File

@ -5,7 +5,7 @@ add_llvm_library(MLIRLinalgToLLVM
${MLIR_MAIN_INCLUDE_DIR}/mlir/Conversion/LinalgToLLVM
)
set(LIBS
MLIRLinalg
MLIRLinalgOps
MLIRLLVMIR
MLIRTransforms
LLVMCore

View File

@ -2,7 +2,7 @@ set(LIBS
MLIRAffineOps
MLIRGPU
MLIRIR
MLIRLinalg
MLIRLinalgOps
MLIRPass
MLIRStandardOps
MLIRSupport

View File

@ -0,0 +1,18 @@
set(LIBS
MLIRLinalgOps
MLIRStandardOps
)
add_llvm_library(MLIRLinalgAnalysis
DependenceAnalysis.cpp
ADDITIONAL_HEADER_DIRS
${MLIR_MAIN_INCLUDE_DIR}/mlir/Dialect/Linalg
DEPENDS
intrinsics_gen
)
add_dependencies(MLIRLinalgAnalysis ${LIBS})
target_link_libraries(MLIRLinalgAnalysis ${LIBS})

View File

@ -1,31 +1,5 @@
add_llvm_library(MLIRLinalg
LinalgRegistration.cpp
Analysis/DependenceAnalysis.cpp
EDSC/Builders.cpp
IR/LinalgOps.cpp
IR/LinalgTypes.cpp
Transforms/Fusion.cpp
Transforms/LinalgTransforms.cpp
Transforms/LinalgToLoops.cpp
Transforms/Promotion.cpp
Transforms/Tiling.cpp
Utils/Utils.cpp
ADDITIONAL_HEADER_DIRS
${MLIR_MAIN_INCLUDE_DIR}/mlir/Dialect/Linalg
DEPENDS
intrinsics_gen
)
add_dependencies(MLIRLinalg
MLIRAffineOps
MLIRAnalysis
MLIREDSC
MLIRLinalgOpsIncGen
MLIRLinalgStructuredOpsIncGen
MLIRLinalgTransformPatternsIncGen
MLIRStandardOps
MLIRStandardToLLVM
MLIRVectorOps
)
add_subdirectory(Analysis)
add_subdirectory(EDSC)
add_subdirectory(IR)
add_subdirectory(Transforms)
add_subdirectory(Utils)

View File

@ -19,6 +19,96 @@ using namespace mlir;
using namespace mlir::edsc;
using namespace mlir::edsc::intrinsics;
using namespace mlir::edsc::ops;
using namespace mlir::linalg;
using namespace mlir::loop;
mlir::edsc::LoopRangeBuilder::LoopRangeBuilder(ValueHandle *iv,
ValueHandle range) {
assert(range.getType() && "expected !linalg.range type");
assert(range.getValue().getDefiningOp() &&
"need operations to extract range parts");
auto rangeOp = cast<RangeOp>(range.getValue().getDefiningOp());
auto lb = rangeOp.min();
auto ub = rangeOp.max();
auto step = rangeOp.step();
auto forOp = OperationHandle::createOp<ForOp>(lb, ub, step);
*iv = ValueHandle(forOp.getInductionVar());
auto *body = forOp.getBody();
enter(body, /*prev=*/1);
}
mlir::edsc::LoopRangeBuilder::LoopRangeBuilder(ValueHandle *iv,
SubViewOp::Range range) {
auto forOp =
OperationHandle::createOp<ForOp>(range.offset, range.size, range.stride);
*iv = ValueHandle(forOp.getInductionVar());
auto *body = forOp.getBody();
enter(body, /*prev=*/1);
}
ValueHandle mlir::edsc::LoopRangeBuilder::
operator()(std::function<void(void)> fun) {
if (fun)
fun();
exit();
return ValueHandle::null();
}
mlir::edsc::LoopNestRangeBuilder::LoopNestRangeBuilder(
ArrayRef<ValueHandle *> ivs, ArrayRef<SubViewOp::Range> ranges) {
loops.reserve(ranges.size());
for (unsigned i = 0, e = ranges.size(); i < e; ++i) {
loops.emplace_back(ivs[i], ranges[i]);
}
assert(loops.size() == ivs.size() && "Mismatch loops vs ivs size");
}
mlir::edsc::LoopNestRangeBuilder::LoopNestRangeBuilder(
ArrayRef<ValueHandle *> ivs, ArrayRef<ValueHandle> ranges) {
loops.reserve(ranges.size());
for (unsigned i = 0, e = ranges.size(); i < e; ++i) {
loops.emplace_back(ivs[i], ranges[i]);
}
assert(loops.size() == ivs.size() && "Mismatch loops vs ivs size");
}
mlir::edsc::LoopNestRangeBuilder::LoopNestRangeBuilder(
ArrayRef<ValueHandle *> ivs, ArrayRef<Value> ranges)
: LoopNestRangeBuilder(
ivs, SmallVector<ValueHandle, 4>(ranges.begin(), ranges.end())) {}
ValueHandle LoopNestRangeBuilder::LoopNestRangeBuilder::
operator()(std::function<void(void)> fun) {
if (fun)
fun();
for (auto &lit : reverse(loops)) {
lit({});
}
return ValueHandle::null();
}
template <>
GenericLoopNestRangeBuilder<loop::ForOp>::GenericLoopNestRangeBuilder(
ArrayRef<edsc::ValueHandle *> ivs, ArrayRef<Value> ranges) {
builder = std::make_unique<LoopNestRangeBuilder>(ivs, ranges);
}
template <>
GenericLoopNestRangeBuilder<AffineForOp>::GenericLoopNestRangeBuilder(
ArrayRef<ValueHandle *> ivs, ArrayRef<Value> ranges) {
SmallVector<ValueHandle, 4> lbs;
SmallVector<ValueHandle, 4> ubs;
SmallVector<int64_t, 4> steps;
for (Value range : ranges) {
assert(range.getType() && "expected linalg.range type");
assert(range.getDefiningOp() && "need operations to extract range parts");
RangeOp rangeOp = cast<RangeOp>(range.getDefiningOp());
lbs.emplace_back(ValueHandle(rangeOp.min()));
ubs.emplace_back(ValueHandle(rangeOp.max()));
steps.emplace_back(ValueHandle(rangeOp.step()));
}
builder = std::make_unique<AffineLoopNestBuilder>(ivs, lbs, ubs, steps);
}
static void getMaxDimIndex(ArrayRef<StructuredIndexed> structuredIndices,
unsigned &pos) {

View File

@ -0,0 +1,20 @@
set(LIBS
MLIREDSC
MLIRIR
MLIRLinalgOps
MLIRLoopOps
MLIRStandardOps
)
add_llvm_library(MLIRLinalgEDSC
Builders.cpp
ADDITIONAL_HEADER_DIRS
${MLIR_MAIN_INCLUDE_DIR}/mlir/Dialect/Linalg
DEPENDS
intrinsics_gen
)
add_dependencies(MLIRLinalgEDSC ${LIBS})
target_link_libraries(MLIRLinalgEDSC ${LIBS})

View File

@ -0,0 +1,23 @@
set(LIBS
MLIRIR
)
add_llvm_library(MLIRLinalgOps
LinalgOps.cpp
LinalgTypes.cpp
LinalgRegistration.cpp
ADDITIONAL_HEADER_DIRS
${MLIR_MAIN_INCLUDE_DIR}/mlir/Dialect/Linalg
DEPENDS
intrinsics_gen
)
add_dependencies(MLIRLinalgOps
${LIBS}
MLIRLinalgOpsIncGen
MLIRLinalgStructuredOpsIncGen
)
target_link_libraries(MLIRLinalgOps ${LIBS})

View File

@ -12,9 +12,6 @@
#include "mlir/Dialect/Linalg/IR/LinalgOps.h"
#include "mlir/Dialect/Linalg/IR/LinalgTypes.h"
#include "mlir/Dialect/Linalg/Utils/Utils.h"
#include "mlir/Dialect/LoopOps/LoopOps.h"
#include "mlir/EDSC/Helpers.h"
#include "mlir/IR/AffineExpr.h"
#include "mlir/IR/AffineMap.h"
#include "mlir/IR/Builders.h"
@ -26,15 +23,12 @@
#include "mlir/Support/Functional.h"
#include "mlir/Support/LLVM.h"
#include "mlir/Support/STLExtras.h"
#include "mlir/Transforms/FoldUtils.h"
#include "llvm/ADT/StringSet.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
using namespace mlir;
using namespace mlir::edsc;
using namespace mlir::edsc::intrinsics;
using namespace mlir::linalg;
///////////////////// Operations defined with Tablegen /////////////////////////

View File

@ -0,0 +1,36 @@
set(LIBS
MLIRAffineOps
MLIRAnalysis
MLIREDSC
MLIRIR
MLIRLinalgAnalysis
MLIRLinalgEDSC
MLIRLinalgOps
MLIRLoopOps
MLIRPass
MLIRStandardOps
MLIRStandardToLLVM
MLIRTransformUtils
MLIRVectorOps
)
add_llvm_library(MLIRLinalgTransforms
Fusion.cpp
LinalgTransforms.cpp
LinalgToLoops.cpp
Promotion.cpp
Tiling.cpp
ADDITIONAL_HEADER_DIRS
${MLIR_MAIN_INCLUDE_DIR}/mlir/Dialect/Linalg
DEPENDS
intrinsics_gen
)
add_dependencies(MLIRLinalgTransforms
${LIBS}
MLIRLinalgTransformPatternsIncGen
)
target_link_libraries(MLIRLinalgTransforms ${LIBS})

View File

@ -1,4 +1,4 @@
//===- LowerToLoops.cpp - conversion from Linalg library ops to loops------===//
//===- LinalgToLoops.cpp - conversion from Linalg library ops to loops-----===//
//
// Part of the MLIR Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
@ -6,6 +6,7 @@
//
//===----------------------------------------------------------------------===//
#include "mlir/Dialect/Linalg/EDSC/Builders.h"
#include "mlir/Dialect/Linalg/IR/LinalgOps.h"
#include "mlir/Dialect/Linalg/IR/LinalgTypes.h"
#include "mlir/Dialect/Linalg/Passes.h"
@ -438,7 +439,7 @@ LogicalResult LinalgOpToLoopsImpl<LoopTy, IndexedValueTy, ConcreteOpTy>::doit(
SmallVector<ValueHandle *, 4> allPIvs =
makeHandlePointers(MutableArrayRef<IndexHandle>(allIvs));
auto loopRanges = emitLoopRanges(scope.getBuilder(), scope.getLocation(),
invertedMap, getViewSizes(linalgOp));
invertedMap, getViewSizes(b, linalgOp));
assert(loopRanges.size() == allIvs.size());
GenericLoopNestRangeBuilder<LoopTy>(allPIvs, loopRanges)([&] {

View File

@ -10,6 +10,7 @@
//
//===----------------------------------------------------------------------===//
#include "mlir/Dialect/Linalg/EDSC/Builders.h"
#include "mlir/Dialect/Linalg/IR/LinalgOps.h"
#include "mlir/Dialect/Linalg/IR/LinalgTypes.h"
#include "mlir/Dialect/Linalg/Passes.h"
@ -333,7 +334,7 @@ mlir::linalg::tileLinalgOp(OpBuilder &b, LinalgOp op, ArrayRef<Value> tileSizes,
b.setInsertionPoint(op);
ScopedContext scope(b, op.getLoc());
// 2. Build the tiled loop ranges.
auto viewSizes = getViewSizes(op);
auto viewSizes = getViewSizes(b, op);
// The flattened loopToOperandRangesMaps is expected to be an invertible
// permutation map (asserted in the inverse calculation).
auto viewSizesToLoopsMap =

View File

@ -0,0 +1,23 @@
set(LIBS
MLIREDSC
MLIRIR
MLIRLinalgOps
MLIRLoopOps
MLIRPass
MLIRStandardOps
MLIRTransformUtils
)
add_llvm_library(MLIRLinalgUtils
Utils.cpp
ADDITIONAL_HEADER_DIRS
${MLIR_MAIN_INCLUDE_DIR}/mlir/Dialect/Linalg
DEPENDS
intrinsics_gen
)
add_dependencies(MLIRLinalgUtils ${LIBS})
target_link_libraries(MLIRLinalgUtils ${LIBS})

View File

@ -13,7 +13,6 @@
#include "mlir/Dialect/Linalg/Utils/Utils.h"
#include "mlir/Dialect/Linalg/IR/LinalgOps.h"
#include "mlir/Dialect/Linalg/IR/LinalgTypes.h"
#include "mlir/Dialect/Linalg/Passes.h"
#include "mlir/Dialect/Linalg/Utils/Intrinsics.h"
#include "mlir/Dialect/LoopOps/LoopOps.h"
#include "mlir/Dialect/StandardOps/Ops.h"
@ -32,102 +31,6 @@ using namespace mlir::linalg;
using namespace mlir::linalg::intrinsics;
using namespace mlir::loop;
mlir::edsc::LoopRangeBuilder::LoopRangeBuilder(ValueHandle *iv,
ValueHandle range) {
assert(range.getType() && "expected !linalg.range type");
assert(range.getValue().getDefiningOp() &&
"need operations to extract range parts");
auto rangeOp = cast<RangeOp>(range.getValue().getDefiningOp());
auto lb = rangeOp.min();
auto ub = rangeOp.max();
auto step = rangeOp.step();
auto forOp = OperationHandle::createOp<ForOp>(lb, ub, step);
*iv = ValueHandle(forOp.getInductionVar());
auto *body = forOp.getBody();
enter(body, /*prev=*/1);
}
mlir::edsc::LoopRangeBuilder::LoopRangeBuilder(ValueHandle *iv,
SubViewOp::Range range) {
auto forOp =
OperationHandle::createOp<ForOp>(range.offset, range.size, range.stride);
*iv = ValueHandle(forOp.getInductionVar());
auto *body = forOp.getBody();
enter(body, /*prev=*/1);
}
ValueHandle
mlir::edsc::LoopRangeBuilder::operator()(std::function<void(void)> fun) {
if (fun)
fun();
exit();
return ValueHandle::null();
}
mlir::edsc::LoopNestRangeBuilder::LoopNestRangeBuilder(
ArrayRef<ValueHandle *> ivs, ArrayRef<SubViewOp::Range> ranges) {
loops.reserve(ranges.size());
for (unsigned i = 0, e = ranges.size(); i < e; ++i) {
loops.emplace_back(ivs[i], ranges[i]);
}
assert(loops.size() == ivs.size() && "Mismatch loops vs ivs size");
}
mlir::edsc::LoopNestRangeBuilder::LoopNestRangeBuilder(
ArrayRef<ValueHandle *> ivs, ArrayRef<ValueHandle> ranges) {
loops.reserve(ranges.size());
for (unsigned i = 0, e = ranges.size(); i < e; ++i) {
loops.emplace_back(ivs[i], ranges[i]);
}
assert(loops.size() == ivs.size() && "Mismatch loops vs ivs size");
}
mlir::edsc::LoopNestRangeBuilder::LoopNestRangeBuilder(
ArrayRef<ValueHandle *> ivs, ArrayRef<Value> ranges)
: LoopNestRangeBuilder(
ivs, SmallVector<ValueHandle, 4>(ranges.begin(), ranges.end())) {}
ValueHandle LoopNestRangeBuilder::LoopNestRangeBuilder::operator()(
std::function<void(void)> fun) {
if (fun)
fun();
for (auto &lit : reverse(loops)) {
lit({});
}
return ValueHandle::null();
}
namespace mlir {
namespace edsc {
template <>
GenericLoopNestRangeBuilder<
loop::ForOp>::GenericLoopNestRangeBuilder(ArrayRef<edsc::ValueHandle *> ivs,
ArrayRef<Value> ranges) {
builder = std::make_unique<LoopNestRangeBuilder>(ivs, ranges);
}
template <>
GenericLoopNestRangeBuilder<
AffineForOp>::GenericLoopNestRangeBuilder(ArrayRef<ValueHandle *> ivs,
ArrayRef<Value> ranges) {
SmallVector<ValueHandle, 4> lbs;
SmallVector<ValueHandle, 4> ubs;
SmallVector<int64_t, 4> steps;
for (Value range : ranges) {
assert(range.getType() && "expected linalg.range type");
assert(range.getDefiningOp() && "need operations to extract range parts");
RangeOp rangeOp = cast<RangeOp>(range.getDefiningOp());
lbs.emplace_back(ValueHandle(rangeOp.min()));
ubs.emplace_back(ValueHandle(rangeOp.max()));
steps.emplace_back(ValueHandle(rangeOp.step()));
}
builder = std::make_unique<AffineLoopNestBuilder>(ivs, lbs, ubs, steps);
}
} // namespace edsc
} // namespace mlir
static Value emitOrFoldComposedAffineApply(OpBuilder &b, Location loc,
AffineMap map,
ArrayRef<Value> operandsRef,

View File

@ -12,11 +12,10 @@
#include <type_traits>
#include "mlir/Dialect/AffineOps/AffineOps.h"
#include "mlir/Dialect/VectorOps/Utils.h"
#include "mlir/Dialect/VectorOps/VectorOps.h"
#include "mlir/Dialect/VectorOps/VectorTransforms.h"
#include "mlir/EDSC/Builders.h"
#include "mlir/EDSC/Helpers.h"
#include "mlir/IR/AffineExpr.h"
#include "mlir/IR/AffineMap.h"
#include "mlir/IR/Attributes.h"

View File

@ -9,7 +9,8 @@ target_link_libraries(mlir-edsc-builder-api-test
MLIRAffineOps
MLIREDSC
MLIRIR
MLIRLinalg
MLIRLinalgEDSC
MLIRLinalgOps
MLIRLoopOps
MLIRStandardOps
MLIRTransforms
@ -21,7 +22,7 @@ target_include_directories(mlir-edsc-builder-api-test PRIVATE ..)
whole_archive_link(mlir-edsc-builder-api-test
MLIRAffineOps
MLIRLinalg
MLIRLinalgOps
MLIRLoopOps
MLIRStandardOps
MLIRTransforms

View File

@ -29,6 +29,9 @@ target_link_libraries(MLIRTestTransforms
MLIRAnalysis
MLIREDSC
MLIRGPU
MLIRLinalgOps
MLIRLinalgTransforms
MLIRLinalgUtils
MLIRLoopOps
MLIRPass
MLIRTestDialect

View File

@ -29,7 +29,7 @@ set(LIBS
MLIRGPUtoNVVMTransforms
MLIRGPUtoROCDLTransforms
MLIRGPUtoSPIRVTransforms
MLIRLinalg
MLIRLinalgOps
MLIRLLVMIR
MLIRLoopOps
MLIRNVVMIR