2018-11-21 12:34:10 -08:00
|
|
|
//===- VectorizerTestPass.cpp - VectorizerTestPass Pass Impl --------------===//
|
2018-11-20 08:36:07 -08:00
|
|
|
//
|
|
|
|
|
// 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.
|
|
|
|
|
// =============================================================================
|
|
|
|
|
//
|
|
|
|
|
// This file implements a simple testing pass for vectorization functionality.
|
|
|
|
|
//
|
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
|
2018-12-06 11:37:38 -08:00
|
|
|
#include "mlir/Analysis/AffineAnalysis.h"
|
2019-01-26 06:59:23 -08:00
|
|
|
#include "mlir/Analysis/NestedMatcher.h"
|
2018-11-21 12:34:10 -08:00
|
|
|
#include "mlir/Analysis/SliceAnalysis.h"
|
2018-11-20 08:36:07 -08:00
|
|
|
#include "mlir/Analysis/VectorAnalysis.h"
|
2019-08-20 15:36:08 -07:00
|
|
|
#include "mlir/Dialect/AffineOps/AffineOps.h"
|
2019-01-04 10:45:58 -08:00
|
|
|
#include "mlir/IR/Builders.h"
|
2019-05-01 11:14:15 -07:00
|
|
|
#include "mlir/IR/Diagnostics.h"
|
2019-01-03 14:29:52 -08:00
|
|
|
#include "mlir/IR/StandardTypes.h"
|
2019-02-19 17:17:46 -08:00
|
|
|
#include "mlir/Pass/Pass.h"
|
2018-11-21 12:34:10 -08:00
|
|
|
#include "mlir/Support/Functional.h"
|
2018-11-20 08:36:07 -08:00
|
|
|
#include "mlir/Support/STLExtras.h"
|
|
|
|
|
#include "mlir/Transforms/Passes.h"
|
|
|
|
|
|
2019-03-27 13:24:05 -07:00
|
|
|
#include "llvm/ADT/STLExtras.h"
|
2018-11-20 08:36:07 -08:00
|
|
|
#include "llvm/Support/CommandLine.h"
|
|
|
|
|
#include "llvm/Support/Debug.h"
|
|
|
|
|
|
2019-05-03 11:07:37 -07:00
|
|
|
#define DEBUG_TYPE "affine-vectorizer-test"
|
2018-11-21 12:34:10 -08:00
|
|
|
|
2018-11-20 08:36:07 -08:00
|
|
|
using namespace mlir;
|
|
|
|
|
|
2018-11-21 12:34:10 -08:00
|
|
|
using llvm::SetVector;
|
|
|
|
|
|
|
|
|
|
using functional::map;
|
|
|
|
|
|
2019-01-25 22:14:04 -08:00
|
|
|
static llvm::cl::OptionCategory clOptionsCategory(DEBUG_TYPE " options");
|
|
|
|
|
|
2018-11-21 12:34:10 -08:00
|
|
|
static llvm::cl::list<int> clTestVectorShapeRatio(
|
|
|
|
|
"vector-shape-ratio",
|
|
|
|
|
llvm::cl::desc("Specify the HW vector size for vectorization"),
|
2019-01-25 22:14:04 -08:00
|
|
|
llvm::cl::ZeroOrMore, llvm::cl::cat(clOptionsCategory));
|
2018-11-21 13:41:59 -08:00
|
|
|
static llvm::cl::opt<bool> clTestForwardSlicingAnalysis(
|
2018-11-21 12:34:10 -08:00
|
|
|
"forward-slicing",
|
2019-01-25 22:14:04 -08:00
|
|
|
llvm::cl::desc("Enable testing forward static slicing and topological sort "
|
|
|
|
|
"functionalities"),
|
|
|
|
|
llvm::cl::cat(clOptionsCategory));
|
2018-11-21 13:41:59 -08:00
|
|
|
static llvm::cl::opt<bool> clTestBackwardSlicingAnalysis(
|
2018-11-21 12:34:10 -08:00
|
|
|
"backward-slicing",
|
2019-01-25 22:14:04 -08:00
|
|
|
llvm::cl::desc("Enable testing backward static slicing and "
|
|
|
|
|
"topological sort functionalities"),
|
|
|
|
|
llvm::cl::cat(clOptionsCategory));
|
2018-11-21 13:41:59 -08:00
|
|
|
static llvm::cl::opt<bool> clTestSlicingAnalysis(
|
2018-11-21 12:34:10 -08:00
|
|
|
"slicing",
|
2019-01-25 22:14:04 -08:00
|
|
|
llvm::cl::desc("Enable testing static slicing and topological sort "
|
|
|
|
|
"functionalities"),
|
|
|
|
|
llvm::cl::cat(clOptionsCategory));
|
2018-12-06 11:37:38 -08:00
|
|
|
static llvm::cl::opt<bool> clTestComposeMaps(
|
|
|
|
|
"compose-maps",
|
|
|
|
|
llvm::cl::desc(
|
2019-01-25 22:14:04 -08:00
|
|
|
"Enable testing the composition of AffineMap where each "
|
2018-12-06 11:37:38 -08:00
|
|
|
"AffineMap in the composition is specified as the affine_map attribute "
|
2019-01-25 22:14:04 -08:00
|
|
|
"in a constant op."),
|
|
|
|
|
llvm::cl::cat(clOptionsCategory));
|
2019-01-04 10:45:58 -08:00
|
|
|
static llvm::cl::opt<bool> clTestNormalizeMaps(
|
|
|
|
|
"normalize-maps",
|
|
|
|
|
llvm::cl::desc(
|
2019-01-25 22:14:04 -08:00
|
|
|
"Enable testing the normalization of AffineAffineApplyOp "
|
2019-01-04 10:45:58 -08:00
|
|
|
"where each AffineAffineApplyOp in the composition is a single output "
|
2019-03-27 14:02:02 -07:00
|
|
|
"operation."),
|
2019-01-25 22:14:04 -08:00
|
|
|
llvm::cl::cat(clOptionsCategory));
|
2018-11-20 08:36:07 -08:00
|
|
|
|
|
|
|
|
namespace {
|
2019-02-27 10:59:29 -08:00
|
|
|
struct VectorizerTestPass : public FunctionPass<VectorizerTestPass> {
|
2018-12-06 11:37:38 -08:00
|
|
|
static constexpr auto kTestAffineMapOpName = "test_affine_map";
|
|
|
|
|
static constexpr auto kTestAffineMapAttrName = "affine_map";
|
2018-11-20 08:36:07 -08:00
|
|
|
|
2019-02-28 14:50:42 -08:00
|
|
|
void runOnFunction() override;
|
2019-03-28 19:53:02 -07:00
|
|
|
void testVectorShapeRatio(llvm::raw_ostream &outs);
|
|
|
|
|
void testForwardSlicing(llvm::raw_ostream &outs);
|
|
|
|
|
void testBackwardSlicing(llvm::raw_ostream &outs);
|
|
|
|
|
void testSlicing(llvm::raw_ostream &outs);
|
|
|
|
|
void testComposeMaps(llvm::raw_ostream &outs);
|
2019-03-25 18:02:49 -07:00
|
|
|
void testNormalizeMaps();
|
2018-11-20 08:36:07 -08:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
} // end anonymous namespace
|
|
|
|
|
|
2019-03-28 19:53:02 -07:00
|
|
|
void VectorizerTestPass::testVectorShapeRatio(llvm::raw_ostream &outs) {
|
2019-07-01 10:29:09 -07:00
|
|
|
auto f = getFunction();
|
2018-11-20 08:36:07 -08:00
|
|
|
using matcher::Op;
|
2019-01-23 14:39:45 -08:00
|
|
|
SmallVector<int64_t, 8> shape(clTestVectorShapeRatio.begin(),
|
|
|
|
|
clTestVectorShapeRatio.end());
|
2019-02-12 11:08:04 -08:00
|
|
|
auto subVectorType =
|
2019-07-01 10:29:09 -07:00
|
|
|
VectorType::get(shape, FloatType::getF32(f.getContext()));
|
2019-03-27 14:02:02 -07:00
|
|
|
// Only filter operations that operate on a strict super-vector and have one
|
2018-11-20 08:36:07 -08:00
|
|
|
// return. This makes testing easier.
|
2019-05-15 07:54:28 -07:00
|
|
|
auto filter = [&](Operation &op) {
|
|
|
|
|
assert(subVectorType.getElementType().isF32() &&
|
2018-11-21 12:34:10 -08:00
|
|
|
"Only f32 supported for now");
|
Cleanup SuperVectorization dialect printing and parsing.
On the read side,
```
%3 = vector_transfer_read %arg0, %i2, %i1, %i0 {permutation_map: (d0, d1, d2)->(d2, d0)} : (memref<?x?x?xf32>, index, index, index) -> vector<32x256xf32>
```
becomes:
```
%3 = vector_transfer_read %arg0[%i2, %i1, %i0] {permutation_map: (d0, d1, d2)->(d2, d0)} : memref<?x?x?xf32>, vector<32x256xf32>
```
On the write side,
```
vector_transfer_write %0, %arg0, %c3, %c3 {permutation_map: (d0, d1)->(d0)} : vector<128xf32>, memref<?x?xf32>, index, index
```
becomes
```
vector_transfer_write %0, %arg0[%c3, %c3] {permutation_map: (d0, d1)->(d0)} : vector<128xf32>, memref<?x?xf32>
```
Documentation will be cleaned up in a followup commit that also extracts a proper .md from the top of the file comments.
PiperOrigin-RevId: 241021879
2019-03-29 11:48:20 -07:00
|
|
|
if (!matcher::operatesOnSuperVectorsOf(op, subVectorType)) {
|
2018-11-20 08:36:07 -08:00
|
|
|
return false;
|
|
|
|
|
}
|
2019-03-27 14:02:02 -07:00
|
|
|
if (op.getNumResults() != 1) {
|
2018-11-20 08:36:07 -08:00
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
};
|
|
|
|
|
auto pat = Op(filter);
|
2019-01-31 07:16:29 -08:00
|
|
|
SmallVector<NestedMatch, 8> matches;
|
|
|
|
|
pat.match(f, &matches);
|
2018-11-20 08:36:07 -08:00
|
|
|
for (auto m : matches) {
|
2019-03-27 08:55:17 -07:00
|
|
|
auto *opInst = m.getMatchedOperation();
|
2018-11-20 08:36:07 -08:00
|
|
|
// This is a unit test that only checks and prints shape ratio.
|
|
|
|
|
// As a consequence we write only Ops with a single return type for the
|
|
|
|
|
// purpose of this test. If we need to test more intricate behavior in the
|
|
|
|
|
// future we can always extend.
|
2018-12-28 16:05:35 -08:00
|
|
|
auto superVectorType = opInst->getResult(0)->getType().cast<VectorType>();
|
2018-11-21 12:34:10 -08:00
|
|
|
auto ratio = shapeRatio(superVectorType, subVectorType);
|
|
|
|
|
if (!ratio.hasValue()) {
|
2019-05-01 12:13:44 -07:00
|
|
|
opInst->emitRemark("NOT MATCHED");
|
2018-11-21 12:34:10 -08:00
|
|
|
} else {
|
2019-03-28 19:53:02 -07:00
|
|
|
outs << "\nmatched: " << *opInst << " with shape ratio: ";
|
|
|
|
|
interleaveComma(MutableArrayRef<unsigned>(*ratio), outs);
|
2018-11-21 12:34:10 -08:00
|
|
|
}
|
2018-11-20 08:36:07 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-01-31 07:16:29 -08:00
|
|
|
static NestedPattern patternTestSlicingOps() {
|
2018-11-21 12:34:10 -08:00
|
|
|
using functional::map;
|
|
|
|
|
using matcher::Op;
|
2019-03-27 14:02:02 -07:00
|
|
|
// Match all operations with the kTestSlicingOpName name.
|
|
|
|
|
auto filter = [](Operation &op) {
|
2019-05-07 14:03:15 -07:00
|
|
|
// Just use a custom op name for this test, it makes life easier.
|
|
|
|
|
return op.getName().getStringRef() == "slicing-test-op";
|
2018-11-21 12:34:10 -08:00
|
|
|
};
|
2019-01-31 07:16:29 -08:00
|
|
|
return Op(filter);
|
2018-11-21 12:34:10 -08:00
|
|
|
}
|
|
|
|
|
|
2019-03-28 19:53:02 -07:00
|
|
|
void VectorizerTestPass::testBackwardSlicing(llvm::raw_ostream &outs) {
|
2019-07-01 10:29:09 -07:00
|
|
|
auto f = getFunction();
|
2019-07-24 10:28:04 -07:00
|
|
|
outs << "\n" << f.getName();
|
2019-03-25 18:02:49 -07:00
|
|
|
|
2019-01-31 07:16:29 -08:00
|
|
|
SmallVector<NestedMatch, 8> matches;
|
|
|
|
|
patternTestSlicingOps().match(f, &matches);
|
2018-11-21 12:34:10 -08:00
|
|
|
for (auto m : matches) {
|
2019-03-27 14:02:02 -07:00
|
|
|
SetVector<Operation *> backwardSlice;
|
2019-03-27 08:55:17 -07:00
|
|
|
getBackwardSlice(m.getMatchedOperation(), &backwardSlice);
|
2019-03-28 19:53:02 -07:00
|
|
|
outs << "\nmatched: " << *m.getMatchedOperation()
|
|
|
|
|
<< " backward static slice: ";
|
2019-05-29 20:31:12 -07:00
|
|
|
for (auto *op : backwardSlice)
|
|
|
|
|
outs << "\n" << *op;
|
2018-11-20 08:36:07 -08:00
|
|
|
}
|
2018-11-21 12:34:10 -08:00
|
|
|
}
|
|
|
|
|
|
2019-03-28 19:53:02 -07:00
|
|
|
void VectorizerTestPass::testForwardSlicing(llvm::raw_ostream &outs) {
|
2019-07-01 10:29:09 -07:00
|
|
|
auto f = getFunction();
|
2019-07-24 10:28:04 -07:00
|
|
|
outs << "\n" << f.getName();
|
|
|
|
|
|
2019-01-31 07:16:29 -08:00
|
|
|
SmallVector<NestedMatch, 8> matches;
|
|
|
|
|
patternTestSlicingOps().match(f, &matches);
|
2018-11-21 12:34:10 -08:00
|
|
|
for (auto m : matches) {
|
2019-03-27 14:02:02 -07:00
|
|
|
SetVector<Operation *> forwardSlice;
|
2019-03-27 08:55:17 -07:00
|
|
|
getForwardSlice(m.getMatchedOperation(), &forwardSlice);
|
2019-03-28 19:53:02 -07:00
|
|
|
outs << "\nmatched: " << *m.getMatchedOperation()
|
|
|
|
|
<< " forward static slice: ";
|
2019-05-29 20:31:12 -07:00
|
|
|
for (auto *op : forwardSlice)
|
|
|
|
|
outs << "\n" << *op;
|
2018-11-21 12:34:10 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-28 19:53:02 -07:00
|
|
|
void VectorizerTestPass::testSlicing(llvm::raw_ostream &outs) {
|
2019-07-01 10:29:09 -07:00
|
|
|
auto f = getFunction();
|
2019-07-24 10:28:04 -07:00
|
|
|
outs << "\n" << f.getName();
|
2019-03-25 18:02:49 -07:00
|
|
|
|
2019-01-31 07:16:29 -08:00
|
|
|
SmallVector<NestedMatch, 8> matches;
|
|
|
|
|
patternTestSlicingOps().match(f, &matches);
|
2018-11-21 12:34:10 -08:00
|
|
|
for (auto m : matches) {
|
2019-03-27 14:02:02 -07:00
|
|
|
SetVector<Operation *> staticSlice = getSlice(m.getMatchedOperation());
|
2019-03-28 19:53:02 -07:00
|
|
|
outs << "\nmatched: " << *m.getMatchedOperation() << " static slice: ";
|
2019-05-29 20:31:12 -07:00
|
|
|
for (auto *op : staticSlice)
|
|
|
|
|
outs << "\n" << *op;
|
2018-11-21 12:34:10 -08:00
|
|
|
}
|
|
|
|
|
}
|
2018-11-20 08:36:07 -08:00
|
|
|
|
2019-03-27 14:02:02 -07:00
|
|
|
static bool customOpWithAffineMapAttribute(Operation &op) {
|
|
|
|
|
return op.getName().getStringRef() ==
|
2018-12-06 11:37:38 -08:00
|
|
|
VectorizerTestPass::kTestAffineMapOpName;
|
|
|
|
|
}
|
|
|
|
|
|
2019-03-28 19:53:02 -07:00
|
|
|
void VectorizerTestPass::testComposeMaps(llvm::raw_ostream &outs) {
|
2019-07-01 10:29:09 -07:00
|
|
|
auto f = getFunction();
|
2019-03-25 18:02:49 -07:00
|
|
|
|
2018-12-06 11:37:38 -08:00
|
|
|
using matcher::Op;
|
|
|
|
|
auto pattern = Op(customOpWithAffineMapAttribute);
|
2019-01-31 07:16:29 -08:00
|
|
|
SmallVector<NestedMatch, 8> matches;
|
|
|
|
|
pattern.match(f, &matches);
|
2018-12-06 11:37:38 -08:00
|
|
|
SmallVector<AffineMap, 4> maps;
|
|
|
|
|
maps.reserve(matches.size());
|
2019-01-31 07:16:29 -08:00
|
|
|
for (auto m : llvm::reverse(matches)) {
|
2019-03-27 08:55:17 -07:00
|
|
|
auto *opInst = m.getMatchedOperation();
|
2018-12-28 16:05:35 -08:00
|
|
|
auto map = opInst->getAttr(VectorizerTestPass::kTestAffineMapAttrName)
|
2018-12-06 11:37:38 -08:00
|
|
|
.cast<AffineMapAttr>()
|
|
|
|
|
.getValue();
|
|
|
|
|
maps.push_back(map);
|
|
|
|
|
}
|
|
|
|
|
AffineMap res;
|
|
|
|
|
for (auto m : maps) {
|
2019-01-07 20:05:14 -08:00
|
|
|
res = res ? res.compose(m) : m;
|
2018-12-06 11:37:38 -08:00
|
|
|
}
|
2019-03-28 19:53:02 -07:00
|
|
|
simplifyAffineMap(res).print(outs << "\nComposed map: ");
|
2018-12-06 11:37:38 -08:00
|
|
|
}
|
|
|
|
|
|
2019-05-11 18:59:54 -07:00
|
|
|
static bool affineApplyOp(Operation &op) { return isa<AffineApplyOp>(op); }
|
2019-01-04 10:45:58 -08:00
|
|
|
|
2019-03-27 14:02:02 -07:00
|
|
|
static bool singleResultAffineApplyOpWithoutUses(Operation &op) {
|
2019-05-11 15:56:50 -07:00
|
|
|
auto app = dyn_cast<AffineApplyOp>(op);
|
2019-03-25 11:13:31 -07:00
|
|
|
return app && app.use_empty();
|
2019-01-04 10:45:58 -08:00
|
|
|
}
|
|
|
|
|
|
2019-03-25 18:02:49 -07:00
|
|
|
void VectorizerTestPass::testNormalizeMaps() {
|
2019-01-04 10:45:58 -08:00
|
|
|
using matcher::Op;
|
|
|
|
|
|
2019-07-01 10:29:09 -07:00
|
|
|
auto f = getFunction();
|
2019-03-25 18:02:49 -07:00
|
|
|
|
2019-01-04 10:45:58 -08:00
|
|
|
// Save matched AffineApplyOp that all need to be erased in the end.
|
|
|
|
|
auto pattern = Op(affineApplyOp);
|
2019-01-31 07:16:29 -08:00
|
|
|
SmallVector<NestedMatch, 8> toErase;
|
|
|
|
|
pattern.match(f, &toErase);
|
2019-01-04 10:45:58 -08:00
|
|
|
{
|
|
|
|
|
// Compose maps.
|
|
|
|
|
auto pattern = Op(singleResultAffineApplyOpWithoutUses);
|
2019-01-31 07:16:29 -08:00
|
|
|
SmallVector<NestedMatch, 8> matches;
|
|
|
|
|
pattern.match(f, &matches);
|
|
|
|
|
for (auto m : matches) {
|
2019-05-11 17:57:32 -07:00
|
|
|
auto app = cast<AffineApplyOp>(m.getMatchedOperation());
|
2019-06-04 19:18:23 -07:00
|
|
|
OpBuilder b(m.getMatchedOperation());
|
2019-03-25 11:13:31 -07:00
|
|
|
SmallVector<Value *, 8> operands(app.getOperands());
|
2019-06-20 15:10:35 -07:00
|
|
|
makeComposedAffineApply(b, app.getLoc(), app.getAffineMap(), operands);
|
2019-01-04 10:45:58 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// We should now be able to erase everything in reverse order in this test.
|
2019-01-31 07:16:29 -08:00
|
|
|
for (auto m : llvm::reverse(toErase)) {
|
2019-03-27 08:55:17 -07:00
|
|
|
m.getMatchedOperation()->erase();
|
2019-01-04 10:45:58 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2019-02-28 14:50:42 -08:00
|
|
|
void VectorizerTestPass::runOnFunction() {
|
2019-01-31 07:16:29 -08:00
|
|
|
// Thread-safe RAII local context, BumpPtrAllocator freed on exit.
|
|
|
|
|
NestedPatternContext mlContext;
|
|
|
|
|
|
2018-12-30 23:10:35 -08:00
|
|
|
// Only support single block functions at this point.
|
2019-07-09 16:17:55 -07:00
|
|
|
FuncOp f = getFunction();
|
2019-03-25 18:02:49 -07:00
|
|
|
if (f.getBlocks().size() != 1)
|
2019-02-28 14:50:42 -08:00
|
|
|
return;
|
2018-12-30 23:10:35 -08:00
|
|
|
|
2019-03-28 19:53:02 -07:00
|
|
|
std::string str;
|
|
|
|
|
llvm::raw_string_ostream outs(str);
|
|
|
|
|
|
2019-03-25 18:02:49 -07:00
|
|
|
if (!clTestVectorShapeRatio.empty())
|
2019-03-28 19:53:02 -07:00
|
|
|
testVectorShapeRatio(outs);
|
2019-03-25 18:02:49 -07:00
|
|
|
|
|
|
|
|
if (clTestForwardSlicingAnalysis)
|
2019-03-28 19:53:02 -07:00
|
|
|
testForwardSlicing(outs);
|
2019-03-25 18:02:49 -07:00
|
|
|
|
|
|
|
|
if (clTestBackwardSlicingAnalysis)
|
2019-03-28 19:53:02 -07:00
|
|
|
testBackwardSlicing(outs);
|
2019-03-25 18:02:49 -07:00
|
|
|
|
|
|
|
|
if (clTestSlicingAnalysis)
|
2019-03-28 19:53:02 -07:00
|
|
|
testSlicing(outs);
|
2019-03-25 18:02:49 -07:00
|
|
|
|
|
|
|
|
if (clTestComposeMaps)
|
2019-03-28 19:53:02 -07:00
|
|
|
testComposeMaps(outs);
|
2019-03-25 18:02:49 -07:00
|
|
|
|
|
|
|
|
if (clTestNormalizeMaps)
|
|
|
|
|
testNormalizeMaps();
|
2019-03-28 19:53:02 -07:00
|
|
|
|
|
|
|
|
if (!outs.str().empty()) {
|
2019-06-25 21:31:54 -07:00
|
|
|
emitRemark(UnknownLoc::get(&getContext()), outs.str());
|
2019-03-28 19:53:02 -07:00
|
|
|
}
|
2018-11-20 08:36:07 -08:00
|
|
|
}
|
|
|
|
|
|
2019-09-13 13:33:46 -07:00
|
|
|
std::unique_ptr<OpPassBase<FuncOp>> mlir::createVectorizerTestPass() {
|
2019-08-17 11:05:35 -07:00
|
|
|
return std::make_unique<VectorizerTestPass>();
|
2018-11-20 08:36:07 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static PassRegistration<VectorizerTestPass>
|
2019-05-03 11:07:37 -07:00
|
|
|
pass("affine-vectorizer-test",
|
|
|
|
|
"Tests vectorizer standalone functionality.");
|
2018-11-20 08:36:07 -08:00
|
|
|
|
|
|
|
|
#undef DEBUG_TYPE
|