Skip to content

Commit 89b395f

Browse files
author
Nicolas Vasilache
committed
[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
1 parent 441410b commit 89b395f

File tree

20 files changed

+291
-208
lines changed

20 files changed

+291
-208
lines changed

mlir/include/mlir/Dialect/Linalg/EDSC/Builders.h

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,64 @@ namespace mlir {
2424
class BlockArgument;
2525

2626
namespace edsc {
27+
28+
/// A LoopRangeBuilder is a generic NestedBuilder for loop.for operations.
29+
/// More specifically it is meant to be used as a temporary object for
30+
/// representing any nested MLIR construct that is "related to" an mlir::Value
31+
/// (for now an induction variable).
32+
class LoopRangeBuilder : public NestedBuilder {
33+
public:
34+
/// Constructs a new loop.for and captures the associated induction
35+
/// variable. A ValueHandle pointer is passed as the first argument and is the
36+
/// *only* way to capture the loop induction variable.
37+
LoopRangeBuilder(ValueHandle *iv, ValueHandle range);
38+
LoopRangeBuilder(ValueHandle *iv, Value range);
39+
LoopRangeBuilder(ValueHandle *iv, SubViewOp::Range range);
40+
41+
LoopRangeBuilder(const LoopRangeBuilder &) = delete;
42+
LoopRangeBuilder(LoopRangeBuilder &&) = default;
43+
44+
LoopRangeBuilder &operator=(const LoopRangeBuilder &) = delete;
45+
LoopRangeBuilder &operator=(LoopRangeBuilder &&) = default;
46+
47+
/// The only purpose of this operator is to serve as a sequence point so that
48+
/// the evaluation of `fun` (which build IR snippets in a scoped fashion) is
49+
/// scoped within a LoopRangeBuilder.
50+
ValueHandle operator()(std::function<void(void)> fun = nullptr);
51+
};
52+
53+
/// Helper class to sugar building loop.for loop nests from ranges.
54+
/// This is similar to edsc::AffineLoopNestBuilder except it works on ranges
55+
/// directly. In the current implementation it produces loop.for operations.
56+
class LoopNestRangeBuilder {
57+
public:
58+
LoopNestRangeBuilder(ArrayRef<edsc::ValueHandle *> ivs,
59+
ArrayRef<edsc::ValueHandle> ranges);
60+
LoopNestRangeBuilder(ArrayRef<edsc::ValueHandle *> ivs,
61+
ArrayRef<Value> ranges);
62+
LoopNestRangeBuilder(ArrayRef<edsc::ValueHandle *> ivs,
63+
ArrayRef<SubViewOp::Range> ranges);
64+
edsc::ValueHandle operator()(std::function<void(void)> fun = nullptr);
65+
66+
private:
67+
SmallVector<LoopRangeBuilder, 4> loops;
68+
};
69+
70+
/// Helper template class for building loop.for and affine.loop nests from
71+
/// ranges.
72+
template <typename LoopTy> class GenericLoopNestRangeBuilder {
73+
public:
74+
GenericLoopNestRangeBuilder(ArrayRef<edsc::ValueHandle *> ivs,
75+
ArrayRef<Value> ranges);
76+
void operator()(std::function<void(void)> fun = nullptr) { (*builder)(fun); }
77+
78+
private:
79+
typedef typename std::conditional<std::is_same<LoopTy, AffineForOp>::value,
80+
AffineLoopNestBuilder,
81+
LoopNestRangeBuilder>::type BuilderType;
82+
std::unique_ptr<BuilderType> builder;
83+
};
84+
2785
enum class IterType { Parallel, Reduction };
2886

2987
inline StringRef toString(IterType t) {

mlir/include/mlir/Dialect/Linalg/Utils/Utils.h

Lines changed: 3 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
#include "mlir/Dialect/Linalg/IR/LinalgOps.h"
1313
#include "mlir/Dialect/LoopOps/LoopOps.h"
1414
#include "mlir/Dialect/StandardOps/Ops.h"
15-
#include "mlir/EDSC/Helpers.h"
1615

1716
#include "llvm/ADT/SetVector.h"
1817

@@ -21,67 +20,6 @@ class AffineExpr;
2120
class AffineMap;
2221
class OperationFolder;
2322

24-
namespace edsc {
25-
26-
/// A LoopRangeBuilder is a generic NestedBuilder for loop.for operations.
27-
/// More specifically it is meant to be used as a temporary object for
28-
/// representing any nested MLIR construct that is "related to" an mlir::Value
29-
/// (for now an induction variable).
30-
class LoopRangeBuilder : public NestedBuilder {
31-
public:
32-
/// Constructs a new loop.for and captures the associated induction
33-
/// variable. A ValueHandle pointer is passed as the first argument and is the
34-
/// *only* way to capture the loop induction variable.
35-
LoopRangeBuilder(ValueHandle *iv, ValueHandle range);
36-
LoopRangeBuilder(ValueHandle *iv, Value range);
37-
LoopRangeBuilder(ValueHandle *iv, SubViewOp::Range range);
38-
39-
LoopRangeBuilder(const LoopRangeBuilder &) = delete;
40-
LoopRangeBuilder(LoopRangeBuilder &&) = default;
41-
42-
LoopRangeBuilder &operator=(const LoopRangeBuilder &) = delete;
43-
LoopRangeBuilder &operator=(LoopRangeBuilder &&) = default;
44-
45-
/// The only purpose of this operator is to serve as a sequence point so that
46-
/// the evaluation of `fun` (which build IR snippets in a scoped fashion) is
47-
/// scoped within a LoopRangeBuilder.
48-
ValueHandle operator()(std::function<void(void)> fun = nullptr);
49-
};
50-
51-
/// Helper class to sugar building loop.for loop nests from ranges.
52-
/// This is similar to edsc::AffineLoopNestBuilder except it works on ranges
53-
/// directly. In the current implementation it produces loop.for operations.
54-
class LoopNestRangeBuilder {
55-
public:
56-
LoopNestRangeBuilder(ArrayRef<edsc::ValueHandle *> ivs,
57-
ArrayRef<edsc::ValueHandle> ranges);
58-
LoopNestRangeBuilder(ArrayRef<edsc::ValueHandle *> ivs,
59-
ArrayRef<Value> ranges);
60-
LoopNestRangeBuilder(ArrayRef<edsc::ValueHandle *> ivs,
61-
ArrayRef<SubViewOp::Range> ranges);
62-
edsc::ValueHandle operator()(std::function<void(void)> fun = nullptr);
63-
64-
private:
65-
SmallVector<LoopRangeBuilder, 4> loops;
66-
};
67-
68-
/// Helper template class for building loop.for and affine.loop nests from
69-
/// ranges.
70-
template <typename LoopTy> class GenericLoopNestRangeBuilder {
71-
public:
72-
GenericLoopNestRangeBuilder(ArrayRef<edsc::ValueHandle *> ivs,
73-
ArrayRef<Value> ranges);
74-
void operator()(std::function<void(void)> fun = nullptr) { (*builder)(fun); }
75-
76-
private:
77-
typedef typename std::conditional<std::is_same<LoopTy, AffineForOp>::value,
78-
AffineLoopNestBuilder,
79-
LoopNestRangeBuilder>::type BuilderType;
80-
std::unique_ptr<BuilderType> builder;
81-
};
82-
83-
} // namespace edsc
84-
8523
namespace linalg {
8624
class LinalgDependenceGraph;
8725

@@ -117,12 +55,13 @@ Optional<FusionInfo> fuseProducerOf(OpBuilder &b, LinalgOp consumer,
11755
/// the inverse, concatenated loopToOperandRangeMaps to this list allows the
11856
/// derivation of loop ranges for any linalgOp.
11957
template <typename ConcreteOp>
120-
SmallVector<Value, 8> getViewSizes(ConcreteOp linalgOp) {
58+
SmallVector<Value, 8> getViewSizes(OpBuilder &builder, ConcreteOp linalgOp) {
59+
auto loc = linalgOp.getLoc();
12160
SmallVector<Value, 8> res;
12261
for (auto v : linalgOp.getInputsAndOutputBuffers()) {
12362
MemRefType t = v.getType().template cast<MemRefType>();
12463
for (unsigned i = 0; i < t.getRank(); ++i)
125-
res.push_back(edsc::intrinsics::dim(v, i));
64+
res.push_back(builder.create<DimOp>(loc, v, i));
12665
}
12766
return res;
12867
}

mlir/lib/Conversion/LinalgToLLVM/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ add_llvm_library(MLIRLinalgToLLVM
55
${MLIR_MAIN_INCLUDE_DIR}/mlir/Conversion/LinalgToLLVM
66
)
77
set(LIBS
8-
MLIRLinalg
8+
MLIRLinalgOps
99
MLIRLLVMIR
1010
MLIRTransforms
1111
LLVMCore

mlir/lib/Conversion/LoopsToGPU/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ set(LIBS
22
MLIRAffineOps
33
MLIRGPU
44
MLIRIR
5-
MLIRLinalg
5+
MLIRLinalgOps
66
MLIRPass
77
MLIRStandardOps
88
MLIRSupport
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
set(LIBS
2+
3+
MLIRLinalgOps
4+
MLIRStandardOps
5+
)
6+
7+
8+
add_llvm_library(MLIRLinalgAnalysis
9+
DependenceAnalysis.cpp
10+
11+
ADDITIONAL_HEADER_DIRS
12+
${MLIR_MAIN_INCLUDE_DIR}/mlir/Dialect/Linalg
13+
DEPENDS
14+
intrinsics_gen
15+
)
16+
17+
add_dependencies(MLIRLinalgAnalysis ${LIBS})
18+
target_link_libraries(MLIRLinalgAnalysis ${LIBS})
Lines changed: 5 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,5 @@
1-
add_llvm_library(MLIRLinalg
2-
LinalgRegistration.cpp
3-
Analysis/DependenceAnalysis.cpp
4-
EDSC/Builders.cpp
5-
IR/LinalgOps.cpp
6-
IR/LinalgTypes.cpp
7-
Transforms/Fusion.cpp
8-
Transforms/LinalgTransforms.cpp
9-
Transforms/LinalgToLoops.cpp
10-
Transforms/Promotion.cpp
11-
Transforms/Tiling.cpp
12-
Utils/Utils.cpp
13-
14-
ADDITIONAL_HEADER_DIRS
15-
${MLIR_MAIN_INCLUDE_DIR}/mlir/Dialect/Linalg
16-
DEPENDS
17-
intrinsics_gen
18-
)
19-
20-
add_dependencies(MLIRLinalg
21-
22-
MLIRAffineOps
23-
MLIRAnalysis
24-
MLIREDSC
25-
MLIRLinalgOpsIncGen
26-
MLIRLinalgStructuredOpsIncGen
27-
MLIRLinalgTransformPatternsIncGen
28-
MLIRStandardOps
29-
MLIRStandardToLLVM
30-
MLIRVectorOps
31-
)
1+
add_subdirectory(Analysis)
2+
add_subdirectory(EDSC)
3+
add_subdirectory(IR)
4+
add_subdirectory(Transforms)
5+
add_subdirectory(Utils)

mlir/lib/Dialect/Linalg/EDSC/Builders.cpp

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,96 @@ using namespace mlir;
1919
using namespace mlir::edsc;
2020
using namespace mlir::edsc::intrinsics;
2121
using namespace mlir::edsc::ops;
22+
using namespace mlir::linalg;
23+
using namespace mlir::loop;
24+
25+
mlir::edsc::LoopRangeBuilder::LoopRangeBuilder(ValueHandle *iv,
26+
ValueHandle range) {
27+
assert(range.getType() && "expected !linalg.range type");
28+
assert(range.getValue().getDefiningOp() &&
29+
"need operations to extract range parts");
30+
auto rangeOp = cast<RangeOp>(range.getValue().getDefiningOp());
31+
auto lb = rangeOp.min();
32+
auto ub = rangeOp.max();
33+
auto step = rangeOp.step();
34+
auto forOp = OperationHandle::createOp<ForOp>(lb, ub, step);
35+
*iv = ValueHandle(forOp.getInductionVar());
36+
auto *body = forOp.getBody();
37+
enter(body, /*prev=*/1);
38+
}
39+
40+
mlir::edsc::LoopRangeBuilder::LoopRangeBuilder(ValueHandle *iv,
41+
SubViewOp::Range range) {
42+
auto forOp =
43+
OperationHandle::createOp<ForOp>(range.offset, range.size, range.stride);
44+
*iv = ValueHandle(forOp.getInductionVar());
45+
auto *body = forOp.getBody();
46+
enter(body, /*prev=*/1);
47+
}
48+
49+
ValueHandle mlir::edsc::LoopRangeBuilder::
50+
operator()(std::function<void(void)> fun) {
51+
if (fun)
52+
fun();
53+
exit();
54+
return ValueHandle::null();
55+
}
56+
57+
mlir::edsc::LoopNestRangeBuilder::LoopNestRangeBuilder(
58+
ArrayRef<ValueHandle *> ivs, ArrayRef<SubViewOp::Range> ranges) {
59+
loops.reserve(ranges.size());
60+
for (unsigned i = 0, e = ranges.size(); i < e; ++i) {
61+
loops.emplace_back(ivs[i], ranges[i]);
62+
}
63+
assert(loops.size() == ivs.size() && "Mismatch loops vs ivs size");
64+
}
65+
66+
mlir::edsc::LoopNestRangeBuilder::LoopNestRangeBuilder(
67+
ArrayRef<ValueHandle *> ivs, ArrayRef<ValueHandle> ranges) {
68+
loops.reserve(ranges.size());
69+
for (unsigned i = 0, e = ranges.size(); i < e; ++i) {
70+
loops.emplace_back(ivs[i], ranges[i]);
71+
}
72+
assert(loops.size() == ivs.size() && "Mismatch loops vs ivs size");
73+
}
74+
75+
mlir::edsc::LoopNestRangeBuilder::LoopNestRangeBuilder(
76+
ArrayRef<ValueHandle *> ivs, ArrayRef<Value> ranges)
77+
: LoopNestRangeBuilder(
78+
ivs, SmallVector<ValueHandle, 4>(ranges.begin(), ranges.end())) {}
79+
80+
ValueHandle LoopNestRangeBuilder::LoopNestRangeBuilder::
81+
operator()(std::function<void(void)> fun) {
82+
if (fun)
83+
fun();
84+
for (auto &lit : reverse(loops)) {
85+
lit({});
86+
}
87+
return ValueHandle::null();
88+
}
89+
90+
template <>
91+
GenericLoopNestRangeBuilder<loop::ForOp>::GenericLoopNestRangeBuilder(
92+
ArrayRef<edsc::ValueHandle *> ivs, ArrayRef<Value> ranges) {
93+
builder = std::make_unique<LoopNestRangeBuilder>(ivs, ranges);
94+
}
95+
96+
template <>
97+
GenericLoopNestRangeBuilder<AffineForOp>::GenericLoopNestRangeBuilder(
98+
ArrayRef<ValueHandle *> ivs, ArrayRef<Value> ranges) {
99+
SmallVector<ValueHandle, 4> lbs;
100+
SmallVector<ValueHandle, 4> ubs;
101+
SmallVector<int64_t, 4> steps;
102+
for (Value range : ranges) {
103+
assert(range.getType() && "expected linalg.range type");
104+
assert(range.getDefiningOp() && "need operations to extract range parts");
105+
RangeOp rangeOp = cast<RangeOp>(range.getDefiningOp());
106+
lbs.emplace_back(ValueHandle(rangeOp.min()));
107+
ubs.emplace_back(ValueHandle(rangeOp.max()));
108+
steps.emplace_back(ValueHandle(rangeOp.step()));
109+
}
110+
builder = std::make_unique<AffineLoopNestBuilder>(ivs, lbs, ubs, steps);
111+
}
22112

23113
static void getMaxDimIndex(ArrayRef<StructuredIndexed> structuredIndices,
24114
unsigned &pos) {
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
set(LIBS
2+
3+
MLIREDSC
4+
MLIRIR
5+
MLIRLinalgOps
6+
MLIRLoopOps
7+
MLIRStandardOps
8+
)
9+
10+
add_llvm_library(MLIRLinalgEDSC
11+
Builders.cpp
12+
13+
ADDITIONAL_HEADER_DIRS
14+
${MLIR_MAIN_INCLUDE_DIR}/mlir/Dialect/Linalg
15+
DEPENDS
16+
intrinsics_gen
17+
)
18+
19+
add_dependencies(MLIRLinalgEDSC ${LIBS})
20+
target_link_libraries(MLIRLinalgEDSC ${LIBS})
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
set(LIBS
2+
3+
MLIRIR
4+
)
5+
6+
add_llvm_library(MLIRLinalgOps
7+
LinalgOps.cpp
8+
LinalgTypes.cpp
9+
LinalgRegistration.cpp
10+
11+
ADDITIONAL_HEADER_DIRS
12+
${MLIR_MAIN_INCLUDE_DIR}/mlir/Dialect/Linalg
13+
DEPENDS
14+
intrinsics_gen
15+
)
16+
17+
add_dependencies(MLIRLinalgOps
18+
19+
${LIBS}
20+
MLIRLinalgOpsIncGen
21+
MLIRLinalgStructuredOpsIncGen
22+
)
23+
target_link_libraries(MLIRLinalgOps ${LIBS})

mlir/lib/Dialect/Linalg/IR/LinalgOps.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,6 @@
1212

1313
#include "mlir/Dialect/Linalg/IR/LinalgOps.h"
1414
#include "mlir/Dialect/Linalg/IR/LinalgTypes.h"
15-
#include "mlir/Dialect/Linalg/Utils/Utils.h"
16-
#include "mlir/Dialect/LoopOps/LoopOps.h"
17-
#include "mlir/EDSC/Helpers.h"
1815
#include "mlir/IR/AffineExpr.h"
1916
#include "mlir/IR/AffineMap.h"
2017
#include "mlir/IR/Builders.h"
@@ -26,15 +23,12 @@
2623
#include "mlir/Support/Functional.h"
2724
#include "mlir/Support/LLVM.h"
2825
#include "mlir/Support/STLExtras.h"
29-
#include "mlir/Transforms/FoldUtils.h"
3026

3127
#include "llvm/ADT/StringSet.h"
3228
#include "llvm/Support/MathExtras.h"
3329
#include "llvm/Support/raw_ostream.h"
3430

3531
using namespace mlir;
36-
using namespace mlir::edsc;
37-
using namespace mlir::edsc::intrinsics;
3832
using namespace mlir::linalg;
3933

4034
///////////////////// Operations defined with Tablegen /////////////////////////

0 commit comments

Comments
 (0)