1fec6c5acSUday Bondhugula //===- TestDialect.cpp - MLIR Dialect for Testing -------------------------===//
2fec6c5acSUday Bondhugula //
3fec6c5acSUday Bondhugula // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4fec6c5acSUday Bondhugula // See https://llvm.org/LICENSE.txt for license information.
5fec6c5acSUday Bondhugula // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6fec6c5acSUday Bondhugula //
7fec6c5acSUday Bondhugula //===----------------------------------------------------------------------===//
8fec6c5acSUday Bondhugula
9fec6c5acSUday Bondhugula #include "TestDialect.h"
1083ef862fSRiver Riddle #include "TestAttributes.h"
11c484c7ddSChia-hung Duan #include "TestInterfaces.h"
122e2cdd0aSRiver Riddle #include "TestTypes.h"
13a54f4eaeSMogball #include "mlir/Dialect/Arithmetic/IR/Arithmetic.h"
143ba14fa0SAlex Zinenko #include "mlir/Dialect/DLTI/DLTI.h"
1523aa5a74SRiver Riddle #include "mlir/Dialect/Func/IR/FuncOps.h"
163ed3e438SMaheshRavishankar #include "mlir/Dialect/Tensor/IR/Tensor.h"
17ea488bd6SRiver Riddle #include "mlir/IR/AsmState.h"
1895aff23eSKrzysztof Drewniak #include "mlir/IR/BuiltinAttributes.h"
1965fcddffSRiver Riddle #include "mlir/IR/BuiltinOps.h"
2095aff23eSKrzysztof Drewniak #include "mlir/IR/Diagnostics.h"
212e2cdd0aSRiver Riddle #include "mlir/IR/DialectImplementation.h"
229e0b5533SMathieu Fehr #include "mlir/IR/ExtensibleDialect.h"
2395aff23eSKrzysztof Drewniak #include "mlir/IR/MLIRContext.h"
2495aff23eSKrzysztof Drewniak #include "mlir/IR/OperationSupport.h"
25fec6c5acSUday Bondhugula #include "mlir/IR/PatternMatch.h"
26fec6c5acSUday Bondhugula #include "mlir/IR/TypeUtilities.h"
275232c5c5SChia-hung Duan #include "mlir/IR/Verifier.h"
2895aff23eSKrzysztof Drewniak #include "mlir/Interfaces/InferIntRangeInterface.h"
29c484c7ddSChia-hung Duan #include "mlir/Reducer/ReductionPatternInterface.h"
30fec6c5acSUday Bondhugula #include "mlir/Transforms/FoldUtils.h"
31fec6c5acSUday Bondhugula #include "mlir/Transforms/InliningUtils.h"
3295aff23eSKrzysztof Drewniak #include "llvm/ADT/SmallString.h"
33a266a210SJeremy Furtek #include "llvm/ADT/StringExtras.h"
34fec6c5acSUday Bondhugula #include "llvm/ADT/StringSwitch.h"
35fec6c5acSUday Bondhugula
367776b19eSStephen Neuendorffer // Include this before the using namespace lines below to
377776b19eSStephen Neuendorffer // test that we don't have namespace dependencies.
38485cc55eSStella Laurenzo #include "TestOpsDialect.cpp.inc"
39485cc55eSStella Laurenzo
407776b19eSStephen Neuendorffer using namespace mlir;
417776b19eSStephen Neuendorffer using namespace test;
427776b19eSStephen Neuendorffer
registerTestDialect(DialectRegistry & registry)437776b19eSStephen Neuendorffer void test::registerTestDialect(DialectRegistry ®istry) {
44f9dc2b70SMehdi Amini registry.insert<TestDialect>();
45f9dc2b70SMehdi Amini }
46f9dc2b70SMehdi Amini
47fec6c5acSUday Bondhugula //===----------------------------------------------------------------------===//
48ea488bd6SRiver Riddle // External Elements Data
49ea488bd6SRiver Riddle //===----------------------------------------------------------------------===//
50ea488bd6SRiver Riddle
getData() const51ea488bd6SRiver Riddle ArrayRef<uint64_t> TestExternalElementsData::getData() const {
52ea488bd6SRiver Riddle ArrayRef<char> data = AsmResourceBlob::getData();
53ea488bd6SRiver Riddle return ArrayRef<uint64_t>((const uint64_t *)data.data(),
54ea488bd6SRiver Riddle data.size() / sizeof(uint64_t));
55ea488bd6SRiver Riddle }
56ea488bd6SRiver Riddle
57ea488bd6SRiver Riddle TestExternalElementsData
allocate(size_t numElements)58ea488bd6SRiver Riddle TestExternalElementsData::allocate(size_t numElements) {
59ea488bd6SRiver Riddle return TestExternalElementsData(
60ea488bd6SRiver Riddle llvm::ArrayRef<uint64_t>(new uint64_t[numElements], numElements),
61ea488bd6SRiver Riddle [](const uint64_t *data, size_t) { delete[] data; },
62ea488bd6SRiver Riddle /*dataIsMutable=*/true);
63ea488bd6SRiver Riddle }
64ea488bd6SRiver Riddle
65ea488bd6SRiver Riddle const TestExternalElementsData *
getData(StringRef name) const66ea488bd6SRiver Riddle TestExternalElementsDataManager::getData(StringRef name) const {
67ea488bd6SRiver Riddle auto it = dataMap.find(name);
68ea488bd6SRiver Riddle return it != dataMap.end() ? &*it->second : nullptr;
69ea488bd6SRiver Riddle }
70ea488bd6SRiver Riddle
71ea488bd6SRiver Riddle std::pair<TestExternalElementsDataManager::DataMap::iterator, bool>
insert(StringRef name)72ea488bd6SRiver Riddle TestExternalElementsDataManager::insert(StringRef name) {
73ea488bd6SRiver Riddle auto it = dataMap.try_emplace(name, nullptr);
74ea488bd6SRiver Riddle if (it.second)
75ea488bd6SRiver Riddle return it;
76ea488bd6SRiver Riddle
77ea488bd6SRiver Riddle llvm::SmallString<32> nameStorage(name);
78ea488bd6SRiver Riddle nameStorage.push_back('_');
79ea488bd6SRiver Riddle size_t nameCounter = 1;
80ea488bd6SRiver Riddle do {
81ea488bd6SRiver Riddle nameStorage += std::to_string(nameCounter++);
82ea488bd6SRiver Riddle auto it = dataMap.try_emplace(nameStorage, nullptr);
83ea488bd6SRiver Riddle if (it.second)
84ea488bd6SRiver Riddle return it;
85ea488bd6SRiver Riddle nameStorage.resize(name.size() + 1);
86ea488bd6SRiver Riddle } while (true);
87ea488bd6SRiver Riddle }
88ea488bd6SRiver Riddle
setData(StringRef name,TestExternalElementsData && data)89ea488bd6SRiver Riddle void TestExternalElementsDataManager::setData(StringRef name,
90ea488bd6SRiver Riddle TestExternalElementsData &&data) {
91ea488bd6SRiver Riddle auto it = dataMap.find(name);
92ea488bd6SRiver Riddle assert(it != dataMap.end() && "data not registered");
93ea488bd6SRiver Riddle it->second = std::make_unique<TestExternalElementsData>(std::move(data));
94ea488bd6SRiver Riddle }
95ea488bd6SRiver Riddle
96ea488bd6SRiver Riddle //===----------------------------------------------------------------------===//
97fec6c5acSUday Bondhugula // TestDialect Interfaces
98fec6c5acSUday Bondhugula //===----------------------------------------------------------------------===//
99fec6c5acSUday Bondhugula
100fec6c5acSUday Bondhugula namespace {
101fec6c5acSUday Bondhugula
102973ddb7dSMehdi Amini /// Testing the correctness of some traits.
103973ddb7dSMehdi Amini static_assert(
104973ddb7dSMehdi Amini llvm::is_detected<OpTrait::has_implicit_terminator_t,
105973ddb7dSMehdi Amini SingleBlockImplicitTerminatorOp>::value,
106973ddb7dSMehdi Amini "has_implicit_terminator_t does not match SingleBlockImplicitTerminatorOp");
107973ddb7dSMehdi Amini static_assert(OpTrait::hasSingleBlockImplicitTerminator<
108973ddb7dSMehdi Amini SingleBlockImplicitTerminatorOp>::value,
109973ddb7dSMehdi Amini "hasSingleBlockImplicitTerminator does not match "
110973ddb7dSMehdi Amini "SingleBlockImplicitTerminatorOp");
111973ddb7dSMehdi Amini
112fec6c5acSUday Bondhugula // Test support for interacting with the AsmPrinter.
113fec6c5acSUday Bondhugula struct TestOpAsmInterface : public OpAsmDialectInterface {
114fec6c5acSUday Bondhugula using OpAsmDialectInterface::OpAsmDialectInterface;
115fec6c5acSUday Bondhugula
116ea488bd6SRiver Riddle //===------------------------------------------------------------------===//
117ea488bd6SRiver Riddle // Aliases
118ea488bd6SRiver Riddle //===------------------------------------------------------------------===//
119ea488bd6SRiver Riddle
getAlias__anonf77d94720211::TestOpAsmInterface12059f59d1cSVladislav Vinogradov AliasResult getAlias(Attribute attr, raw_ostream &os) const final {
121a463ea50SRiver Riddle StringAttr strAttr = attr.dyn_cast<StringAttr>();
122a463ea50SRiver Riddle if (!strAttr)
12359f59d1cSVladislav Vinogradov return AliasResult::NoAlias;
124a463ea50SRiver Riddle
125a463ea50SRiver Riddle // Check the contents of the string attribute to see what the test alias
126a463ea50SRiver Riddle // should be named.
127a463ea50SRiver Riddle Optional<StringRef> aliasName =
128a463ea50SRiver Riddle StringSwitch<Optional<StringRef>>(strAttr.getValue())
129a463ea50SRiver Riddle .Case("alias_test:dot_in_name", StringRef("test.alias"))
130a463ea50SRiver Riddle .Case("alias_test:trailing_digit", StringRef("test_alias0"))
131a463ea50SRiver Riddle .Case("alias_test:prefixed_digit", StringRef("0_test_alias"))
132a463ea50SRiver Riddle .Case("alias_test:sanitize_conflict_a",
133a463ea50SRiver Riddle StringRef("test_alias_conflict0"))
134a463ea50SRiver Riddle .Case("alias_test:sanitize_conflict_b",
135a463ea50SRiver Riddle StringRef("test_alias_conflict0_"))
136eb6c63cbSVladislav Vinogradov .Case("alias_test:tensor_encoding", StringRef("test_encoding"))
137a463ea50SRiver Riddle .Default(llvm::None);
138a463ea50SRiver Riddle if (!aliasName)
13959f59d1cSVladislav Vinogradov return AliasResult::NoAlias;
140a463ea50SRiver Riddle
141a463ea50SRiver Riddle os << *aliasName;
14259f59d1cSVladislav Vinogradov return AliasResult::FinalAlias;
14359f59d1cSVladislav Vinogradov }
14459f59d1cSVladislav Vinogradov
getAlias__anonf77d94720211::TestOpAsmInterface14559f59d1cSVladislav Vinogradov AliasResult getAlias(Type type, raw_ostream &os) const final {
14659f59d1cSVladislav Vinogradov if (auto tupleType = type.dyn_cast<TupleType>()) {
14759f59d1cSVladislav Vinogradov if (tupleType.size() > 0 &&
14859f59d1cSVladislav Vinogradov llvm::all_of(tupleType.getTypes(), [](Type elemType) {
14959f59d1cSVladislav Vinogradov return elemType.isa<SimpleAType>();
15059f59d1cSVladislav Vinogradov })) {
15159f59d1cSVladislav Vinogradov os << "test_tuple";
15259f59d1cSVladislav Vinogradov return AliasResult::FinalAlias;
15359f59d1cSVladislav Vinogradov }
15459f59d1cSVladislav Vinogradov }
155c6390f19SVladislav Vinogradov if (auto intType = type.dyn_cast<TestIntegerType>()) {
156c6390f19SVladislav Vinogradov if (intType.getSignedness() ==
157c6390f19SVladislav Vinogradov TestIntegerType::SignednessSemantics::Unsigned &&
158c6390f19SVladislav Vinogradov intType.getWidth() == 8) {
159c6390f19SVladislav Vinogradov os << "test_ui8";
160c6390f19SVladislav Vinogradov return AliasResult::FinalAlias;
161c6390f19SVladislav Vinogradov }
162c6390f19SVladislav Vinogradov }
163d4102861SMin-Yih Hsu if (auto recType = type.dyn_cast<TestRecursiveType>()) {
164d4102861SMin-Yih Hsu if (recType.getName() == "type_to_alias") {
165d4102861SMin-Yih Hsu // We only make alias for a specific recursive type.
166d4102861SMin-Yih Hsu os << "testrec";
167d4102861SMin-Yih Hsu return AliasResult::FinalAlias;
168d4102861SMin-Yih Hsu }
169d4102861SMin-Yih Hsu }
17059f59d1cSVladislav Vinogradov return AliasResult::NoAlias;
171a463ea50SRiver Riddle }
172ea488bd6SRiver Riddle
173ea488bd6SRiver Riddle //===------------------------------------------------------------------===//
174ea488bd6SRiver Riddle // Resources
175ea488bd6SRiver Riddle //===------------------------------------------------------------------===//
176ea488bd6SRiver Riddle
177ea488bd6SRiver Riddle std::string
getResourceKey__anonf77d94720211::TestOpAsmInterface178ea488bd6SRiver Riddle getResourceKey(const AsmDialectResourceHandle &handle) const override {
179ea488bd6SRiver Riddle return cast<TestExternalElementsDataHandle>(handle).getKey().str();
180ea488bd6SRiver Riddle }
181ea488bd6SRiver Riddle
182ea488bd6SRiver Riddle FailureOr<AsmDialectResourceHandle>
declareResource__anonf77d94720211::TestOpAsmInterface183ea488bd6SRiver Riddle declareResource(StringRef key) const final {
184ea488bd6SRiver Riddle TestDialect *dialect = cast<TestDialect>(getDialect());
185ea488bd6SRiver Riddle TestExternalElementsDataManager &mgr = dialect->getExternalDataManager();
186ea488bd6SRiver Riddle
187ea488bd6SRiver Riddle // Resolve the reference by inserting a new entry into the manager.
188ea488bd6SRiver Riddle auto it = mgr.insert(key).first;
189ea488bd6SRiver Riddle return TestExternalElementsDataHandle(&*it, dialect);
190ea488bd6SRiver Riddle }
191ea488bd6SRiver Riddle
parseResource__anonf77d94720211::TestOpAsmInterface192ea488bd6SRiver Riddle LogicalResult parseResource(AsmParsedResourceEntry &entry) const final {
193ea488bd6SRiver Riddle TestDialect *dialect = cast<TestDialect>(getDialect());
194ea488bd6SRiver Riddle TestExternalElementsDataManager &mgr = dialect->getExternalDataManager();
195ea488bd6SRiver Riddle
196ea488bd6SRiver Riddle // The resource entries are external constant data.
197ea488bd6SRiver Riddle auto blobAllocFn = [](unsigned size, unsigned align) {
198ea488bd6SRiver Riddle assert(align == alignof(uint64_t) && "unexpected data alignment");
199ea488bd6SRiver Riddle return TestExternalElementsData::allocate(size / sizeof(uint64_t));
200ea488bd6SRiver Riddle };
201ea488bd6SRiver Riddle FailureOr<AsmResourceBlob> blob = entry.parseAsBlob(blobAllocFn);
202ea488bd6SRiver Riddle if (failed(blob))
203ea488bd6SRiver Riddle return failure();
204ea488bd6SRiver Riddle
205ea488bd6SRiver Riddle mgr.setData(entry.getKey(), std::move(*blob));
206ea488bd6SRiver Riddle return success();
207ea488bd6SRiver Riddle }
208ea488bd6SRiver Riddle
209ea488bd6SRiver Riddle void
buildResources__anonf77d94720211::TestOpAsmInterface210ea488bd6SRiver Riddle buildResources(Operation *op,
211ea488bd6SRiver Riddle const SetVector<AsmDialectResourceHandle> &referencedResources,
212ea488bd6SRiver Riddle AsmResourceBuilder &provider) const final {
213ea488bd6SRiver Riddle for (const AsmDialectResourceHandle &handle : referencedResources) {
214ea488bd6SRiver Riddle const auto &testHandle = cast<TestExternalElementsDataHandle>(handle);
215ea488bd6SRiver Riddle provider.buildBlob(testHandle.getKey(), testHandle.getData()->getData());
216ea488bd6SRiver Riddle }
217ea488bd6SRiver Riddle }
218fec6c5acSUday Bondhugula };
219fec6c5acSUday Bondhugula
220b28e3db8SMehdi Amini struct TestDialectFoldInterface : public DialectFoldInterface {
221b28e3db8SMehdi Amini using DialectFoldInterface::DialectFoldInterface;
222fec6c5acSUday Bondhugula
223fec6c5acSUday Bondhugula /// Registered hook to check if the given region, which is attached to an
224fec6c5acSUday Bondhugula /// operation that is *not* isolated from above, should be used when
225fec6c5acSUday Bondhugula /// materializing constants.
shouldMaterializeInto__anonf77d94720211::TestDialectFoldInterface226fec6c5acSUday Bondhugula bool shouldMaterializeInto(Region *region) const final {
227fec6c5acSUday Bondhugula // If this is a one region operation, then insert into it.
228fec6c5acSUday Bondhugula return isa<OneRegionOp>(region->getParentOp());
229fec6c5acSUday Bondhugula }
230fec6c5acSUday Bondhugula };
231fec6c5acSUday Bondhugula
232fec6c5acSUday Bondhugula /// This class defines the interface for handling inlining with standard
233fec6c5acSUday Bondhugula /// operations.
234fec6c5acSUday Bondhugula struct TestInlinerInterface : public DialectInlinerInterface {
235fec6c5acSUday Bondhugula using DialectInlinerInterface::DialectInlinerInterface;
236fec6c5acSUday Bondhugula
237fec6c5acSUday Bondhugula //===--------------------------------------------------------------------===//
238fec6c5acSUday Bondhugula // Analysis Hooks
239fec6c5acSUday Bondhugula //===--------------------------------------------------------------------===//
240fec6c5acSUday Bondhugula
isLegalToInline__anonf77d94720211::TestInlinerInterface241fa417479SRiver Riddle bool isLegalToInline(Operation *call, Operation *callable,
242fa417479SRiver Riddle bool wouldBeCloned) const final {
243501fda01SRiver Riddle // Don't allow inlining calls that are marked `noinline`.
244501fda01SRiver Riddle return !call->hasAttr("noinline");
245501fda01SRiver Riddle }
isLegalToInline__anonf77d94720211::TestInlinerInterface246fa417479SRiver Riddle bool isLegalToInline(Region *, Region *, bool,
247fa417479SRiver Riddle BlockAndValueMapping &) const final {
248fec6c5acSUday Bondhugula // Inlining into test dialect regions is legal.
249fec6c5acSUday Bondhugula return true;
250fec6c5acSUday Bondhugula }
isLegalToInline__anonf77d94720211::TestInlinerInterface251fa417479SRiver Riddle bool isLegalToInline(Operation *, Region *, bool,
252fec6c5acSUday Bondhugula BlockAndValueMapping &) const final {
253fec6c5acSUday Bondhugula return true;
254fec6c5acSUday Bondhugula }
255fec6c5acSUday Bondhugula
shouldAnalyzeRecursively__anonf77d94720211::TestInlinerInterface256fec6c5acSUday Bondhugula bool shouldAnalyzeRecursively(Operation *op) const final {
257fec6c5acSUday Bondhugula // Analyze recursively if this is not a functional region operation, it
258fec6c5acSUday Bondhugula // froms a separate functional scope.
259fec6c5acSUday Bondhugula return !isa<FunctionalRegionOp>(op);
260fec6c5acSUday Bondhugula }
261fec6c5acSUday Bondhugula
262fec6c5acSUday Bondhugula //===--------------------------------------------------------------------===//
263fec6c5acSUday Bondhugula // Transformation Hooks
264fec6c5acSUday Bondhugula //===--------------------------------------------------------------------===//
265fec6c5acSUday Bondhugula
266fec6c5acSUday Bondhugula /// Handle the given inlined terminator by replacing it with a new operation
267fec6c5acSUday Bondhugula /// as necessary.
handleTerminator__anonf77d94720211::TestInlinerInterface268fec6c5acSUday Bondhugula void handleTerminator(Operation *op,
269fec6c5acSUday Bondhugula ArrayRef<Value> valuesToRepl) const final {
270fec6c5acSUday Bondhugula // Only handle "test.return" here.
271fec6c5acSUday Bondhugula auto returnOp = dyn_cast<TestReturnOp>(op);
272fec6c5acSUday Bondhugula if (!returnOp)
273fec6c5acSUday Bondhugula return;
274fec6c5acSUday Bondhugula
275fec6c5acSUday Bondhugula // Replace the values directly with the return operands.
276fec6c5acSUday Bondhugula assert(returnOp.getNumOperands() == valuesToRepl.size());
277fec6c5acSUday Bondhugula for (const auto &it : llvm::enumerate(returnOp.getOperands()))
278fec6c5acSUday Bondhugula valuesToRepl[it.index()].replaceAllUsesWith(it.value());
279fec6c5acSUday Bondhugula }
280fec6c5acSUday Bondhugula
281fec6c5acSUday Bondhugula /// Attempt to materialize a conversion for a type mismatch between a call
282fec6c5acSUday Bondhugula /// from this dialect, and a callable region. This method should generate an
283fec6c5acSUday Bondhugula /// operation that takes 'input' as the only operand, and produces a single
284fec6c5acSUday Bondhugula /// result of 'resultType'. If a conversion can not be generated, nullptr
285fec6c5acSUday Bondhugula /// should be returned.
materializeCallConversion__anonf77d94720211::TestInlinerInterface286fec6c5acSUday Bondhugula Operation *materializeCallConversion(OpBuilder &builder, Value input,
287fec6c5acSUday Bondhugula Type resultType,
288fec6c5acSUday Bondhugula Location conversionLoc) const final {
289fec6c5acSUday Bondhugula // Only allow conversion for i16/i32 types.
290fec6c5acSUday Bondhugula if (!(resultType.isSignlessInteger(16) ||
291fec6c5acSUday Bondhugula resultType.isSignlessInteger(32)) ||
292fec6c5acSUday Bondhugula !(input.getType().isSignlessInteger(16) ||
293fec6c5acSUday Bondhugula input.getType().isSignlessInteger(32)))
294fec6c5acSUday Bondhugula return nullptr;
295fec6c5acSUday Bondhugula return builder.create<TestCastOp>(conversionLoc, resultType, input);
296fec6c5acSUday Bondhugula }
2970e760a08SJacques Pienaar
processInlinedCallBlocks__anonf77d94720211::TestInlinerInterface2980e760a08SJacques Pienaar void processInlinedCallBlocks(
2990e760a08SJacques Pienaar Operation *call,
3000e760a08SJacques Pienaar iterator_range<Region::iterator> inlinedBlocks) const final {
3010e760a08SJacques Pienaar if (!isa<ConversionCallOp>(call))
3020e760a08SJacques Pienaar return;
3030e760a08SJacques Pienaar
3040e760a08SJacques Pienaar // Set attributed on all ops in the inlined blocks.
3050e760a08SJacques Pienaar for (Block &block : inlinedBlocks) {
3060e760a08SJacques Pienaar block.walk([&](Operation *op) {
3070e760a08SJacques Pienaar op->setAttr("inlined_conversion", UnitAttr::get(call->getContext()));
3080e760a08SJacques Pienaar });
3090e760a08SJacques Pienaar }
3100e760a08SJacques Pienaar }
311fec6c5acSUday Bondhugula };
312c484c7ddSChia-hung Duan
313c484c7ddSChia-hung Duan struct TestReductionPatternInterface : public DialectReductionPatternInterface {
314c484c7ddSChia-hung Duan public:
TestReductionPatternInterface__anonf77d94720211::TestReductionPatternInterface315c484c7ddSChia-hung Duan TestReductionPatternInterface(Dialect *dialect)
316c484c7ddSChia-hung Duan : DialectReductionPatternInterface(dialect) {}
317c484c7ddSChia-hung Duan
populateReductionPatterns__anonf77d94720211::TestReductionPatternInterface318b3891f28SMehdi Amini void populateReductionPatterns(RewritePatternSet &patterns) const final {
319c484c7ddSChia-hung Duan populateTestReductionPatterns(patterns);
320c484c7ddSChia-hung Duan }
321c484c7ddSChia-hung Duan };
322c484c7ddSChia-hung Duan
323be0a7e9fSMehdi Amini } // namespace
324fec6c5acSUday Bondhugula
325fec6c5acSUday Bondhugula //===----------------------------------------------------------------------===//
3269e0b5533SMathieu Fehr // Dynamic operations
3279e0b5533SMathieu Fehr //===----------------------------------------------------------------------===//
3289e0b5533SMathieu Fehr
getDynamicGenericOp(TestDialect * dialect)3299e0b5533SMathieu Fehr std::unique_ptr<DynamicOpDefinition> getDynamicGenericOp(TestDialect *dialect) {
3309e0b5533SMathieu Fehr return DynamicOpDefinition::get(
3319e0b5533SMathieu Fehr "dynamic_generic", dialect, [](Operation *op) { return success(); },
3329e0b5533SMathieu Fehr [](Operation *op) { return success(); });
3339e0b5533SMathieu Fehr }
3349e0b5533SMathieu Fehr
3359e0b5533SMathieu Fehr std::unique_ptr<DynamicOpDefinition>
getDynamicOneOperandTwoResultsOp(TestDialect * dialect)3369e0b5533SMathieu Fehr getDynamicOneOperandTwoResultsOp(TestDialect *dialect) {
3379e0b5533SMathieu Fehr return DynamicOpDefinition::get(
3389e0b5533SMathieu Fehr "dynamic_one_operand_two_results", dialect,
3399e0b5533SMathieu Fehr [](Operation *op) {
3409e0b5533SMathieu Fehr if (op->getNumOperands() != 1) {
3419e0b5533SMathieu Fehr op->emitOpError()
3429e0b5533SMathieu Fehr << "expected 1 operand, but had " << op->getNumOperands();
3439e0b5533SMathieu Fehr return failure();
3449e0b5533SMathieu Fehr }
3459e0b5533SMathieu Fehr if (op->getNumResults() != 2) {
3469e0b5533SMathieu Fehr op->emitOpError()
3479e0b5533SMathieu Fehr << "expected 2 results, but had " << op->getNumResults();
3489e0b5533SMathieu Fehr return failure();
3499e0b5533SMathieu Fehr }
3509e0b5533SMathieu Fehr return success();
3519e0b5533SMathieu Fehr },
3529e0b5533SMathieu Fehr [](Operation *op) { return success(); });
3539e0b5533SMathieu Fehr }
3549e0b5533SMathieu Fehr
3559e0b5533SMathieu Fehr std::unique_ptr<DynamicOpDefinition>
getDynamicCustomParserPrinterOp(TestDialect * dialect)3569e0b5533SMathieu Fehr getDynamicCustomParserPrinterOp(TestDialect *dialect) {
3579e0b5533SMathieu Fehr auto verifier = [](Operation *op) {
3589e0b5533SMathieu Fehr if (op->getNumOperands() == 0 && op->getNumResults() == 0)
3599e0b5533SMathieu Fehr return success();
3609e0b5533SMathieu Fehr op->emitError() << "operation should have no operands and no results";
3619e0b5533SMathieu Fehr return failure();
3629e0b5533SMathieu Fehr };
3639e0b5533SMathieu Fehr auto regionVerifier = [](Operation *op) { return success(); };
3649e0b5533SMathieu Fehr
3659e0b5533SMathieu Fehr auto parser = [](OpAsmParser &parser, OperationState &state) {
3669e0b5533SMathieu Fehr return parser.parseKeyword("custom_keyword");
3679e0b5533SMathieu Fehr };
3689e0b5533SMathieu Fehr
3699e0b5533SMathieu Fehr auto printer = [](Operation *op, OpAsmPrinter &printer, llvm::StringRef) {
3709e0b5533SMathieu Fehr printer << op->getName() << " custom_keyword";
3719e0b5533SMathieu Fehr };
3729e0b5533SMathieu Fehr
3739e0b5533SMathieu Fehr return DynamicOpDefinition::get("dynamic_custom_parser_printer", dialect,
3749e0b5533SMathieu Fehr verifier, regionVerifier, parser, printer);
3759e0b5533SMathieu Fehr }
3769e0b5533SMathieu Fehr
3779e0b5533SMathieu Fehr //===----------------------------------------------------------------------===//
378fec6c5acSUday Bondhugula // TestDialect
379fec6c5acSUday Bondhugula //===----------------------------------------------------------------------===//
380fec6c5acSUday Bondhugula
381d905c103SMehdi Amini static void testSideEffectOpGetEffect(
382d905c103SMehdi Amini Operation *op,
383d905c103SMehdi Amini SmallVectorImpl<SideEffects::EffectInstance<TestEffects::Effect>> &effects);
384d905c103SMehdi Amini
385d905c103SMehdi Amini // This is the implementation of a dialect fallback for `TestEffectOpInterface`.
386d905c103SMehdi Amini struct TestOpEffectInterfaceFallback
387d905c103SMehdi Amini : public TestEffectOpInterface::FallbackModel<
388d905c103SMehdi Amini TestOpEffectInterfaceFallback> {
classofTestOpEffectInterfaceFallback389d905c103SMehdi Amini static bool classof(Operation *op) {
390d905c103SMehdi Amini bool isSupportedOp =
391d905c103SMehdi Amini op->getName().getStringRef() == "test.unregistered_side_effect_op";
392d905c103SMehdi Amini assert(isSupportedOp && "Unexpected dispatch");
393d905c103SMehdi Amini return isSupportedOp;
394d905c103SMehdi Amini }
395d905c103SMehdi Amini
396d905c103SMehdi Amini void
getEffectsTestOpEffectInterfaceFallback397d905c103SMehdi Amini getEffects(Operation *op,
398d905c103SMehdi Amini SmallVectorImpl<SideEffects::EffectInstance<TestEffects::Effect>>
399d905c103SMehdi Amini &effects) const {
400d905c103SMehdi Amini testSideEffectOpGetEffect(op, effects);
401d905c103SMehdi Amini }
402d905c103SMehdi Amini };
403d905c103SMehdi Amini
initialize()404575b22b5SMehdi Amini void TestDialect::initialize() {
40531bb8efdSRiver Riddle registerAttributes();
40631bb8efdSRiver Riddle registerTypes();
407fec6c5acSUday Bondhugula addOperations<
408fec6c5acSUday Bondhugula #define GET_OP_LIST
409fec6c5acSUday Bondhugula #include "TestOps.cpp.inc"
410fec6c5acSUday Bondhugula >();
4119e0b5533SMathieu Fehr registerDynamicOp(getDynamicGenericOp(this));
4129e0b5533SMathieu Fehr registerDynamicOp(getDynamicOneOperandTwoResultsOp(this));
4139e0b5533SMathieu Fehr registerDynamicOp(getDynamicCustomParserPrinterOp(this));
4149e0b5533SMathieu Fehr
415b28e3db8SMehdi Amini addInterfaces<TestOpAsmInterface, TestDialectFoldInterface,
416c484c7ddSChia-hung Duan TestInlinerInterface, TestReductionPatternInterface>();
417fec6c5acSUday Bondhugula allowUnknownOperations();
418d905c103SMehdi Amini
419d905c103SMehdi Amini // Instantiate our fallback op interface that we'll use on specific
420d905c103SMehdi Amini // unregistered op.
421d905c103SMehdi Amini fallbackEffectOpInterfaces = new TestOpEffectInterfaceFallback;
422d905c103SMehdi Amini }
~TestDialect()423d905c103SMehdi Amini TestDialect::~TestDialect() {
424d905c103SMehdi Amini delete static_cast<TestOpEffectInterfaceFallback *>(
425d905c103SMehdi Amini fallbackEffectOpInterfaces);
426fec6c5acSUday Bondhugula }
427fec6c5acSUday Bondhugula
materializeConstant(OpBuilder & builder,Attribute value,Type type,Location loc)428186c1549SRiver Riddle Operation *TestDialect::materializeConstant(OpBuilder &builder, Attribute value,
429186c1549SRiver Riddle Type type, Location loc) {
430186c1549SRiver Riddle return builder.create<TestOpConstant>(loc, type, value);
431186c1549SRiver Riddle }
432186c1549SRiver Riddle
inferReturnTypes(::mlir::MLIRContext * context,::llvm::Optional<::mlir::Location> location,::mlir::ValueRange operands,::mlir::DictionaryAttr attributes,::mlir::RegionRange regions,::llvm::SmallVectorImpl<::mlir::Type> & inferredReturnTypes)43305594de2SJacques Pienaar ::mlir::LogicalResult FormatInferType2Op::inferReturnTypes(
43405594de2SJacques Pienaar ::mlir::MLIRContext *context, ::llvm::Optional<::mlir::Location> location,
43505594de2SJacques Pienaar ::mlir::ValueRange operands, ::mlir::DictionaryAttr attributes,
43605594de2SJacques Pienaar ::mlir::RegionRange regions,
43705594de2SJacques Pienaar ::llvm::SmallVectorImpl<::mlir::Type> &inferredReturnTypes) {
43805594de2SJacques Pienaar inferredReturnTypes.assign({::mlir::IntegerType::get(context, 16)});
43905594de2SJacques Pienaar return ::mlir::success();
44005594de2SJacques Pienaar }
44105594de2SJacques Pienaar
getRegisteredInterfaceForOp(TypeID typeID,OperationName opName)442d905c103SMehdi Amini void *TestDialect::getRegisteredInterfaceForOp(TypeID typeID,
443d905c103SMehdi Amini OperationName opName) {
444d905c103SMehdi Amini if (opName.getIdentifier() == "test.unregistered_side_effect_op" &&
445d905c103SMehdi Amini typeID == TypeID::get<TestEffectOpInterface>())
446d905c103SMehdi Amini return fallbackEffectOpInterfaces;
447d905c103SMehdi Amini return nullptr;
448d905c103SMehdi Amini }
449d905c103SMehdi Amini
verifyOperationAttribute(Operation * op,NamedAttribute namedAttr)450fec6c5acSUday Bondhugula LogicalResult TestDialect::verifyOperationAttribute(Operation *op,
451fec6c5acSUday Bondhugula NamedAttribute namedAttr) {
4520c7890c8SRiver Riddle if (namedAttr.getName() == "test.invalid_attr")
453fec6c5acSUday Bondhugula return op->emitError() << "invalid to use 'test.invalid_attr'";
454fec6c5acSUday Bondhugula return success();
455fec6c5acSUday Bondhugula }
456fec6c5acSUday Bondhugula
verifyRegionArgAttribute(Operation * op,unsigned regionIndex,unsigned argIndex,NamedAttribute namedAttr)457fec6c5acSUday Bondhugula LogicalResult TestDialect::verifyRegionArgAttribute(Operation *op,
458fec6c5acSUday Bondhugula unsigned regionIndex,
459fec6c5acSUday Bondhugula unsigned argIndex,
460fec6c5acSUday Bondhugula NamedAttribute namedAttr) {
4610c7890c8SRiver Riddle if (namedAttr.getName() == "test.invalid_attr")
462fec6c5acSUday Bondhugula return op->emitError() << "invalid to use 'test.invalid_attr'";
463fec6c5acSUday Bondhugula return success();
464fec6c5acSUday Bondhugula }
465fec6c5acSUday Bondhugula
466fec6c5acSUday Bondhugula LogicalResult
verifyRegionResultAttribute(Operation * op,unsigned regionIndex,unsigned resultIndex,NamedAttribute namedAttr)467fec6c5acSUday Bondhugula TestDialect::verifyRegionResultAttribute(Operation *op, unsigned regionIndex,
468fec6c5acSUday Bondhugula unsigned resultIndex,
469fec6c5acSUday Bondhugula NamedAttribute namedAttr) {
4700c7890c8SRiver Riddle if (namedAttr.getName() == "test.invalid_attr")
471fec6c5acSUday Bondhugula return op->emitError() << "invalid to use 'test.invalid_attr'";
472fec6c5acSUday Bondhugula return success();
473fec6c5acSUday Bondhugula }
474fec6c5acSUday Bondhugula
475a0c776fcSMehdi Amini Optional<Dialect::ParseOpHook>
getParseOperationHook(StringRef opName) const476a0c776fcSMehdi Amini TestDialect::getParseOperationHook(StringRef opName) const {
477a0c776fcSMehdi Amini if (opName == "test.dialect_custom_printer") {
478a0c776fcSMehdi Amini return ParseOpHook{[](OpAsmParser &parser, OperationState &state) {
479a0c776fcSMehdi Amini return parser.parseKeyword("custom_format");
480a0c776fcSMehdi Amini }};
481a0c776fcSMehdi Amini }
4820845635eSMogball if (opName == "test.dialect_custom_format_fallback") {
4830845635eSMogball return ParseOpHook{[](OpAsmParser &parser, OperationState &state) {
4840845635eSMogball return parser.parseKeyword("custom_format_fallback");
4850845635eSMogball }};
4860845635eSMogball }
487122e6858SAlex Zinenko if (opName == "test.dialect_custom_printer.with.dot") {
488122e6858SAlex Zinenko return ParseOpHook{[](OpAsmParser &parser, OperationState &state) {
489122e6858SAlex Zinenko return ParseResult::success();
490122e6858SAlex Zinenko }};
491122e6858SAlex Zinenko }
492a0c776fcSMehdi Amini return None;
493a0c776fcSMehdi Amini }
494a0c776fcSMehdi Amini
495fd87963eSMehdi Amini llvm::unique_function<void(Operation *, OpAsmPrinter &)>
getOperationPrinter(Operation * op) const496fd87963eSMehdi Amini TestDialect::getOperationPrinter(Operation *op) const {
497a0c776fcSMehdi Amini StringRef opName = op->getName().getStringRef();
498a0c776fcSMehdi Amini if (opName == "test.dialect_custom_printer") {
499fd87963eSMehdi Amini return [](Operation *op, OpAsmPrinter &printer) {
500c41b16c2SMehdi Amini printer.getStream() << " custom_format";
501fd87963eSMehdi Amini };
502a0c776fcSMehdi Amini }
5030845635eSMogball if (opName == "test.dialect_custom_format_fallback") {
5040845635eSMogball return [](Operation *op, OpAsmPrinter &printer) {
5050845635eSMogball printer.getStream() << " custom_format_fallback";
5060845635eSMogball };
5070845635eSMogball }
508fd87963eSMehdi Amini return {};
509a0c776fcSMehdi Amini }
510a0c776fcSMehdi Amini
511fec6c5acSUday Bondhugula //===----------------------------------------------------------------------===//
512fec6c5acSUday Bondhugula // TestBranchOp
513fec6c5acSUday Bondhugula //===----------------------------------------------------------------------===//
514fec6c5acSUday Bondhugula
getSuccessorOperands(unsigned index)5150c789db5SMarkus Böck SuccessorOperands TestBranchOp::getSuccessorOperands(unsigned index) {
516fec6c5acSUday Bondhugula assert(index == 0 && "invalid successor index");
5170c789db5SMarkus Böck return SuccessorOperands(getTargetOperandsMutable());
518fec6c5acSUday Bondhugula }
519fec6c5acSUday Bondhugula
520fec6c5acSUday Bondhugula //===----------------------------------------------------------------------===//
521c14ba3c4SMarkus Böck // TestProducingBranchOp
522c14ba3c4SMarkus Böck //===----------------------------------------------------------------------===//
523c14ba3c4SMarkus Böck
getSuccessorOperands(unsigned index)5240c789db5SMarkus Böck SuccessorOperands TestProducingBranchOp::getSuccessorOperands(unsigned index) {
525c14ba3c4SMarkus Böck assert(index <= 1 && "invalid successor index");
526a7865228SMarkus Böck if (index == 1)
5270c789db5SMarkus Böck return SuccessorOperands(getFirstOperandsMutable());
5280c789db5SMarkus Böck return SuccessorOperands(getSecondOperandsMutable());
5290c789db5SMarkus Böck }
5300c789db5SMarkus Böck
5310c789db5SMarkus Böck //===----------------------------------------------------------------------===//
5320c789db5SMarkus Böck // TestProducingBranchOp
5330c789db5SMarkus Böck //===----------------------------------------------------------------------===//
5340c789db5SMarkus Böck
getSuccessorOperands(unsigned index)5350c789db5SMarkus Böck SuccessorOperands TestInternalBranchOp::getSuccessorOperands(unsigned index) {
5360c789db5SMarkus Böck assert(index <= 1 && "invalid successor index");
5370c789db5SMarkus Böck if (index == 0)
5380c789db5SMarkus Böck return SuccessorOperands(0, getSuccessOperandsMutable());
5390c789db5SMarkus Böck return SuccessorOperands(1, getErrorOperandsMutable());
540c14ba3c4SMarkus Böck }
541c14ba3c4SMarkus Böck
542c14ba3c4SMarkus Böck //===----------------------------------------------------------------------===//
543108ca7a7SMatthias Springer // TestDialectCanonicalizerOp
544108ca7a7SMatthias Springer //===----------------------------------------------------------------------===//
545108ca7a7SMatthias Springer
546108ca7a7SMatthias Springer static LogicalResult
dialectCanonicalizationPattern(TestDialectCanonicalizerOp op,PatternRewriter & rewriter)547108ca7a7SMatthias Springer dialectCanonicalizationPattern(TestDialectCanonicalizerOp op,
548108ca7a7SMatthias Springer PatternRewriter &rewriter) {
549a54f4eaeSMogball rewriter.replaceOpWithNewOp<arith::ConstantOp>(
550a54f4eaeSMogball op, rewriter.getI32IntegerAttr(42));
551108ca7a7SMatthias Springer return success();
552108ca7a7SMatthias Springer }
553108ca7a7SMatthias Springer
getCanonicalizationPatterns(RewritePatternSet & results) const554108ca7a7SMatthias Springer void TestDialect::getCanonicalizationPatterns(
555108ca7a7SMatthias Springer RewritePatternSet &results) const {
556108ca7a7SMatthias Springer results.add(&dialectCanonicalizationPattern);
557108ca7a7SMatthias Springer }
558108ca7a7SMatthias Springer
559108ca7a7SMatthias Springer //===----------------------------------------------------------------------===//
56050f82e68SRiver Riddle // TestCallOp
56150f82e68SRiver Riddle //===----------------------------------------------------------------------===//
56250f82e68SRiver Riddle
verifySymbolUses(SymbolTableCollection & symbolTable)56350f82e68SRiver Riddle LogicalResult TestCallOp::verifySymbolUses(SymbolTableCollection &symbolTable) {
56450f82e68SRiver Riddle // Check that the callee attribute was specified.
56550f82e68SRiver Riddle auto fnAttr = (*this)->getAttrOfType<FlatSymbolRefAttr>("callee");
56650f82e68SRiver Riddle if (!fnAttr)
56750f82e68SRiver Riddle return emitOpError("requires a 'callee' symbol reference attribute");
56850f82e68SRiver Riddle if (!symbolTable.lookupNearestSymbolFrom<FunctionOpInterface>(*this, fnAttr))
56950f82e68SRiver Riddle return emitOpError() << "'" << fnAttr.getValue()
57050f82e68SRiver Riddle << "' does not reference a valid function";
57150f82e68SRiver Riddle return success();
57250f82e68SRiver Riddle }
57350f82e68SRiver Riddle
57450f82e68SRiver Riddle //===----------------------------------------------------------------------===//
575f4ef77cbSRiver Riddle // TestFoldToCallOp
576f4ef77cbSRiver Riddle //===----------------------------------------------------------------------===//
577f4ef77cbSRiver Riddle
578f4ef77cbSRiver Riddle namespace {
579f4ef77cbSRiver Riddle struct FoldToCallOpPattern : public OpRewritePattern<FoldToCallOp> {
580f4ef77cbSRiver Riddle using OpRewritePattern<FoldToCallOp>::OpRewritePattern;
581f4ef77cbSRiver Riddle
matchAndRewrite__anonf77d94721311::FoldToCallOpPattern582f4ef77cbSRiver Riddle LogicalResult matchAndRewrite(FoldToCallOp op,
583f4ef77cbSRiver Riddle PatternRewriter &rewriter) const override {
58423aa5a74SRiver Riddle rewriter.replaceOpWithNewOp<func::CallOp>(op, TypeRange(),
58523aa5a74SRiver Riddle op.getCalleeAttr(), ValueRange());
586f4ef77cbSRiver Riddle return success();
587f4ef77cbSRiver Riddle }
588f4ef77cbSRiver Riddle };
589be0a7e9fSMehdi Amini } // namespace
590f4ef77cbSRiver Riddle
getCanonicalizationPatterns(RewritePatternSet & results,MLIRContext * context)591dc4e913bSChris Lattner void FoldToCallOp::getCanonicalizationPatterns(RewritePatternSet &results,
592dc4e913bSChris Lattner MLIRContext *context) {
593dc4e913bSChris Lattner results.add<FoldToCallOpPattern>(context);
594f4ef77cbSRiver Riddle }
595f4ef77cbSRiver Riddle
596f4ef77cbSRiver Riddle //===----------------------------------------------------------------------===//
59788c6e25eSRiver Riddle // Test Format* operations
59888c6e25eSRiver Riddle //===----------------------------------------------------------------------===//
59988c6e25eSRiver Riddle
60088c6e25eSRiver Riddle //===----------------------------------------------------------------------===//
60188c6e25eSRiver Riddle // Parsing
60288c6e25eSRiver Riddle
parseCustomOptionalOperand(OpAsmParser & parser,Optional<OpAsmParser::UnresolvedOperand> & optOperand)603e13d23bcSMarkus Böck static ParseResult parseCustomOptionalOperand(
604e13d23bcSMarkus Böck OpAsmParser &parser, Optional<OpAsmParser::UnresolvedOperand> &optOperand) {
6055bec1ea7SShraiysh Vaishay if (succeeded(parser.parseOptionalLParen())) {
6065bec1ea7SShraiysh Vaishay optOperand.emplace();
6075bec1ea7SShraiysh Vaishay if (parser.parseOperand(*optOperand) || parser.parseRParen())
6085bec1ea7SShraiysh Vaishay return failure();
6095bec1ea7SShraiysh Vaishay }
6105bec1ea7SShraiysh Vaishay return success();
6115bec1ea7SShraiysh Vaishay }
6125bec1ea7SShraiysh Vaishay
parseCustomDirectiveOperands(OpAsmParser & parser,OpAsmParser::UnresolvedOperand & operand,Optional<OpAsmParser::UnresolvedOperand> & optOperand,SmallVectorImpl<OpAsmParser::UnresolvedOperand> & varOperands)61388c6e25eSRiver Riddle static ParseResult parseCustomDirectiveOperands(
614e13d23bcSMarkus Böck OpAsmParser &parser, OpAsmParser::UnresolvedOperand &operand,
615e13d23bcSMarkus Böck Optional<OpAsmParser::UnresolvedOperand> &optOperand,
616e13d23bcSMarkus Böck SmallVectorImpl<OpAsmParser::UnresolvedOperand> &varOperands) {
61788c6e25eSRiver Riddle if (parser.parseOperand(operand))
61888c6e25eSRiver Riddle return failure();
61988c6e25eSRiver Riddle if (succeeded(parser.parseOptionalComma())) {
62088c6e25eSRiver Riddle optOperand.emplace();
62188c6e25eSRiver Riddle if (parser.parseOperand(*optOperand))
62288c6e25eSRiver Riddle return failure();
62388c6e25eSRiver Riddle }
62488c6e25eSRiver Riddle if (parser.parseArrow() || parser.parseLParen() ||
62588c6e25eSRiver Riddle parser.parseOperandList(varOperands) || parser.parseRParen())
62688c6e25eSRiver Riddle return failure();
62788c6e25eSRiver Riddle return success();
62888c6e25eSRiver Riddle }
62988c6e25eSRiver Riddle static ParseResult
parseCustomDirectiveResults(OpAsmParser & parser,Type & operandType,Type & optOperandType,SmallVectorImpl<Type> & varOperandTypes)63088c6e25eSRiver Riddle parseCustomDirectiveResults(OpAsmParser &parser, Type &operandType,
63188c6e25eSRiver Riddle Type &optOperandType,
63288c6e25eSRiver Riddle SmallVectorImpl<Type> &varOperandTypes) {
63388c6e25eSRiver Riddle if (parser.parseColon())
63488c6e25eSRiver Riddle return failure();
63588c6e25eSRiver Riddle
63688c6e25eSRiver Riddle if (parser.parseType(operandType))
63788c6e25eSRiver Riddle return failure();
63888c6e25eSRiver Riddle if (succeeded(parser.parseOptionalComma())) {
63988c6e25eSRiver Riddle if (parser.parseType(optOperandType))
64088c6e25eSRiver Riddle return failure();
64188c6e25eSRiver Riddle }
64288c6e25eSRiver Riddle if (parser.parseArrow() || parser.parseLParen() ||
64388c6e25eSRiver Riddle parser.parseTypeList(varOperandTypes) || parser.parseRParen())
64488c6e25eSRiver Riddle return failure();
64588c6e25eSRiver Riddle return success();
64688c6e25eSRiver Riddle }
64793fd30baSNicolas Vasilache static ParseResult
parseCustomDirectiveWithTypeRefs(OpAsmParser & parser,Type operandType,Type optOperandType,const SmallVectorImpl<Type> & varOperandTypes)64893fd30baSNicolas Vasilache parseCustomDirectiveWithTypeRefs(OpAsmParser &parser, Type operandType,
64993fd30baSNicolas Vasilache Type optOperandType,
65093fd30baSNicolas Vasilache const SmallVectorImpl<Type> &varOperandTypes) {
65193fd30baSNicolas Vasilache if (parser.parseKeyword("type_refs_capture"))
65293fd30baSNicolas Vasilache return failure();
65393fd30baSNicolas Vasilache
65493fd30baSNicolas Vasilache Type operandType2, optOperandType2;
65593fd30baSNicolas Vasilache SmallVector<Type, 1> varOperandTypes2;
65693fd30baSNicolas Vasilache if (parseCustomDirectiveResults(parser, operandType2, optOperandType2,
65793fd30baSNicolas Vasilache varOperandTypes2))
65893fd30baSNicolas Vasilache return failure();
65993fd30baSNicolas Vasilache
66093fd30baSNicolas Vasilache if (operandType != operandType2 || optOperandType != optOperandType2 ||
66193fd30baSNicolas Vasilache varOperandTypes != varOperandTypes2)
66293fd30baSNicolas Vasilache return failure();
66393fd30baSNicolas Vasilache
66493fd30baSNicolas Vasilache return success();
66593fd30baSNicolas Vasilache }
parseCustomDirectiveOperandsAndTypes(OpAsmParser & parser,OpAsmParser::UnresolvedOperand & operand,Optional<OpAsmParser::UnresolvedOperand> & optOperand,SmallVectorImpl<OpAsmParser::UnresolvedOperand> & varOperands,Type & operandType,Type & optOperandType,SmallVectorImpl<Type> & varOperandTypes)66688c6e25eSRiver Riddle static ParseResult parseCustomDirectiveOperandsAndTypes(
667e13d23bcSMarkus Böck OpAsmParser &parser, OpAsmParser::UnresolvedOperand &operand,
668e13d23bcSMarkus Böck Optional<OpAsmParser::UnresolvedOperand> &optOperand,
669e13d23bcSMarkus Böck SmallVectorImpl<OpAsmParser::UnresolvedOperand> &varOperands,
670e13d23bcSMarkus Böck Type &operandType, Type &optOperandType,
671e13d23bcSMarkus Böck SmallVectorImpl<Type> &varOperandTypes) {
67288c6e25eSRiver Riddle if (parseCustomDirectiveOperands(parser, operand, optOperand, varOperands) ||
67388c6e25eSRiver Riddle parseCustomDirectiveResults(parser, operandType, optOperandType,
67488c6e25eSRiver Riddle varOperandTypes))
67588c6e25eSRiver Riddle return failure();
67688c6e25eSRiver Riddle return success();
67788c6e25eSRiver Riddle }
parseCustomDirectiveRegions(OpAsmParser & parser,Region & region,SmallVectorImpl<std::unique_ptr<Region>> & varRegions)678eaeadce9SRiver Riddle static ParseResult parseCustomDirectiveRegions(
679eaeadce9SRiver Riddle OpAsmParser &parser, Region ®ion,
680eaeadce9SRiver Riddle SmallVectorImpl<std::unique_ptr<Region>> &varRegions) {
681eaeadce9SRiver Riddle if (parser.parseRegion(region))
682eaeadce9SRiver Riddle return failure();
683eaeadce9SRiver Riddle if (failed(parser.parseOptionalComma()))
684eaeadce9SRiver Riddle return success();
685eaeadce9SRiver Riddle std::unique_ptr<Region> varRegion = std::make_unique<Region>();
686eaeadce9SRiver Riddle if (parser.parseRegion(*varRegion))
687eaeadce9SRiver Riddle return failure();
688eaeadce9SRiver Riddle varRegions.emplace_back(std::move(varRegion));
689eaeadce9SRiver Riddle return success();
690eaeadce9SRiver Riddle }
69188c6e25eSRiver Riddle static ParseResult
parseCustomDirectiveSuccessors(OpAsmParser & parser,Block * & successor,SmallVectorImpl<Block * > & varSuccessors)69288c6e25eSRiver Riddle parseCustomDirectiveSuccessors(OpAsmParser &parser, Block *&successor,
69388c6e25eSRiver Riddle SmallVectorImpl<Block *> &varSuccessors) {
69488c6e25eSRiver Riddle if (parser.parseSuccessor(successor))
69588c6e25eSRiver Riddle return failure();
69688c6e25eSRiver Riddle if (failed(parser.parseOptionalComma()))
69788c6e25eSRiver Riddle return success();
69888c6e25eSRiver Riddle Block *varSuccessor;
69988c6e25eSRiver Riddle if (parser.parseSuccessor(varSuccessor))
70088c6e25eSRiver Riddle return failure();
70188c6e25eSRiver Riddle varSuccessors.append(2, varSuccessor);
70288c6e25eSRiver Riddle return success();
70388c6e25eSRiver Riddle }
parseCustomDirectiveAttributes(OpAsmParser & parser,IntegerAttr & attr,IntegerAttr & optAttr)704d14cfe10SMike Urbach static ParseResult parseCustomDirectiveAttributes(OpAsmParser &parser,
705d14cfe10SMike Urbach IntegerAttr &attr,
706d14cfe10SMike Urbach IntegerAttr &optAttr) {
707d14cfe10SMike Urbach if (parser.parseAttribute(attr))
708d14cfe10SMike Urbach return failure();
709d14cfe10SMike Urbach if (succeeded(parser.parseOptionalComma())) {
710d14cfe10SMike Urbach if (parser.parseAttribute(optAttr))
711d14cfe10SMike Urbach return failure();
712d14cfe10SMike Urbach }
713d14cfe10SMike Urbach return success();
714d14cfe10SMike Urbach }
71588c6e25eSRiver Riddle
parseCustomDirectiveAttrDict(OpAsmParser & parser,NamedAttrList & attrs)716035e12e6SJohn Demme static ParseResult parseCustomDirectiveAttrDict(OpAsmParser &parser,
717035e12e6SJohn Demme NamedAttrList &attrs) {
718035e12e6SJohn Demme return parser.parseOptionalAttrDict(attrs);
719035e12e6SJohn Demme }
parseCustomDirectiveOptionalOperandRef(OpAsmParser & parser,Optional<OpAsmParser::UnresolvedOperand> & optOperand)7206e3292b0SRiver Riddle static ParseResult parseCustomDirectiveOptionalOperandRef(
721e13d23bcSMarkus Böck OpAsmParser &parser, Optional<OpAsmParser::UnresolvedOperand> &optOperand) {
7226e3292b0SRiver Riddle int64_t operandCount = 0;
7236e3292b0SRiver Riddle if (parser.parseInteger(operandCount))
7246e3292b0SRiver Riddle return failure();
7256e3292b0SRiver Riddle bool expectedOptionalOperand = operandCount == 0;
726064a08cdSKazu Hirata return success(expectedOptionalOperand != optOperand.has_value());
7276e3292b0SRiver Riddle }
728035e12e6SJohn Demme
72988c6e25eSRiver Riddle //===----------------------------------------------------------------------===//
73088c6e25eSRiver Riddle // Printing
73188c6e25eSRiver Riddle
printCustomOptionalOperand(OpAsmPrinter & printer,Operation *,Value optOperand)7325bec1ea7SShraiysh Vaishay static void printCustomOptionalOperand(OpAsmPrinter &printer, Operation *,
7335bec1ea7SShraiysh Vaishay Value optOperand) {
7345bec1ea7SShraiysh Vaishay if (optOperand)
7355bec1ea7SShraiysh Vaishay printer << "(" << optOperand << ") ";
7365bec1ea7SShraiysh Vaishay }
7375bec1ea7SShraiysh Vaishay
printCustomDirectiveOperands(OpAsmPrinter & printer,Operation *,Value operand,Value optOperand,OperandRange varOperands)738035e12e6SJohn Demme static void printCustomDirectiveOperands(OpAsmPrinter &printer, Operation *,
739035e12e6SJohn Demme Value operand, Value optOperand,
74088c6e25eSRiver Riddle OperandRange varOperands) {
74188c6e25eSRiver Riddle printer << operand;
74288c6e25eSRiver Riddle if (optOperand)
74388c6e25eSRiver Riddle printer << ", " << optOperand;
74488c6e25eSRiver Riddle printer << " -> (" << varOperands << ")";
74588c6e25eSRiver Riddle }
printCustomDirectiveResults(OpAsmPrinter & printer,Operation *,Type operandType,Type optOperandType,TypeRange varOperandTypes)746035e12e6SJohn Demme static void printCustomDirectiveResults(OpAsmPrinter &printer, Operation *,
747035e12e6SJohn Demme Type operandType, Type optOperandType,
74888c6e25eSRiver Riddle TypeRange varOperandTypes) {
74988c6e25eSRiver Riddle printer << " : " << operandType;
75088c6e25eSRiver Riddle if (optOperandType)
75188c6e25eSRiver Riddle printer << ", " << optOperandType;
75288c6e25eSRiver Riddle printer << " -> (" << varOperandTypes << ")";
75388c6e25eSRiver Riddle }
printCustomDirectiveWithTypeRefs(OpAsmPrinter & printer,Operation * op,Type operandType,Type optOperandType,TypeRange varOperandTypes)75493fd30baSNicolas Vasilache static void printCustomDirectiveWithTypeRefs(OpAsmPrinter &printer,
755035e12e6SJohn Demme Operation *op, Type operandType,
75693fd30baSNicolas Vasilache Type optOperandType,
75793fd30baSNicolas Vasilache TypeRange varOperandTypes) {
75893fd30baSNicolas Vasilache printer << " type_refs_capture ";
759035e12e6SJohn Demme printCustomDirectiveResults(printer, op, operandType, optOperandType,
76093fd30baSNicolas Vasilache varOperandTypes);
76193fd30baSNicolas Vasilache }
printCustomDirectiveOperandsAndTypes(OpAsmPrinter & printer,Operation * op,Value operand,Value optOperand,OperandRange varOperands,Type operandType,Type optOperandType,TypeRange varOperandTypes)762035e12e6SJohn Demme static void printCustomDirectiveOperandsAndTypes(
763035e12e6SJohn Demme OpAsmPrinter &printer, Operation *op, Value operand, Value optOperand,
764035e12e6SJohn Demme OperandRange varOperands, Type operandType, Type optOperandType,
76588c6e25eSRiver Riddle TypeRange varOperandTypes) {
766035e12e6SJohn Demme printCustomDirectiveOperands(printer, op, operand, optOperand, varOperands);
767035e12e6SJohn Demme printCustomDirectiveResults(printer, op, operandType, optOperandType,
76888c6e25eSRiver Riddle varOperandTypes);
76988c6e25eSRiver Riddle }
printCustomDirectiveRegions(OpAsmPrinter & printer,Operation *,Region & region,MutableArrayRef<Region> varRegions)770035e12e6SJohn Demme static void printCustomDirectiveRegions(OpAsmPrinter &printer, Operation *,
771035e12e6SJohn Demme Region ®ion,
772eaeadce9SRiver Riddle MutableArrayRef<Region> varRegions) {
773eaeadce9SRiver Riddle printer.printRegion(region);
774eaeadce9SRiver Riddle if (!varRegions.empty()) {
775eaeadce9SRiver Riddle printer << ", ";
776eaeadce9SRiver Riddle for (Region ®ion : varRegions)
777eaeadce9SRiver Riddle printer.printRegion(region);
778eaeadce9SRiver Riddle }
779eaeadce9SRiver Riddle }
printCustomDirectiveSuccessors(OpAsmPrinter & printer,Operation *,Block * successor,SuccessorRange varSuccessors)780035e12e6SJohn Demme static void printCustomDirectiveSuccessors(OpAsmPrinter &printer, Operation *,
78188c6e25eSRiver Riddle Block *successor,
78288c6e25eSRiver Riddle SuccessorRange varSuccessors) {
78388c6e25eSRiver Riddle printer << successor;
78488c6e25eSRiver Riddle if (!varSuccessors.empty())
78588c6e25eSRiver Riddle printer << ", " << varSuccessors.front();
78688c6e25eSRiver Riddle }
printCustomDirectiveAttributes(OpAsmPrinter & printer,Operation *,Attribute attribute,Attribute optAttribute)787035e12e6SJohn Demme static void printCustomDirectiveAttributes(OpAsmPrinter &printer, Operation *,
788d14cfe10SMike Urbach Attribute attribute,
789d14cfe10SMike Urbach Attribute optAttribute) {
790d14cfe10SMike Urbach printer << attribute;
791d14cfe10SMike Urbach if (optAttribute)
792d14cfe10SMike Urbach printer << ", " << optAttribute;
793d14cfe10SMike Urbach }
79488c6e25eSRiver Riddle
printCustomDirectiveAttrDict(OpAsmPrinter & printer,Operation * op,DictionaryAttr attrs)795035e12e6SJohn Demme static void printCustomDirectiveAttrDict(OpAsmPrinter &printer, Operation *op,
796fc5cf50eSRiver Riddle DictionaryAttr attrs) {
797fc5cf50eSRiver Riddle printer.printOptionalAttrDict(attrs.getValue());
798035e12e6SJohn Demme }
7996e3292b0SRiver Riddle
printCustomDirectiveOptionalOperandRef(OpAsmPrinter & printer,Operation * op,Value optOperand)8006e3292b0SRiver Riddle static void printCustomDirectiveOptionalOperandRef(OpAsmPrinter &printer,
8016e3292b0SRiver Riddle Operation *op,
8026e3292b0SRiver Riddle Value optOperand) {
8036e3292b0SRiver Riddle printer << (optOperand ? "1" : "0");
8046e3292b0SRiver Riddle }
8056e3292b0SRiver Riddle
80688c6e25eSRiver Riddle //===----------------------------------------------------------------------===//
807fec6c5acSUday Bondhugula // Test IsolatedRegionOp - parse passthrough region arguments.
808fec6c5acSUday Bondhugula //===----------------------------------------------------------------------===//
809fec6c5acSUday Bondhugula
parse(OpAsmParser & parser,OperationState & result)810d7f0083dSRiver Riddle ParseResult IsolatedRegionOp::parse(OpAsmParser &parser,
811fec6c5acSUday Bondhugula OperationState &result) {
812fec6c5acSUday Bondhugula // Parse the input operand.
813d85eb4e2SChris Lattner OpAsmParser::Argument argInfo;
814d85eb4e2SChris Lattner argInfo.type = parser.getBuilder().getIndexType();
815d85eb4e2SChris Lattner if (parser.parseOperand(argInfo.ssaName) ||
816d85eb4e2SChris Lattner parser.resolveOperand(argInfo.ssaName, argInfo.type, result.operands))
817fec6c5acSUday Bondhugula return failure();
818fec6c5acSUday Bondhugula
819fec6c5acSUday Bondhugula // Parse the body region, and reuse the operand info as the argument info.
820fec6c5acSUday Bondhugula Region *body = result.addRegion();
821d85eb4e2SChris Lattner return parser.parseRegion(*body, argInfo, /*enableNameShadowing=*/true);
822fec6c5acSUday Bondhugula }
823fec6c5acSUday Bondhugula
print(OpAsmPrinter & p)824d7f0083dSRiver Riddle void IsolatedRegionOp::print(OpAsmPrinter &p) {
825fec6c5acSUday Bondhugula p << "test.isolated_region ";
826d7f0083dSRiver Riddle p.printOperand(getOperand());
827d7f0083dSRiver Riddle p.shadowRegionArgs(getRegion(), getOperand());
8285c36ee8dSMogball p << ' ';
829d7f0083dSRiver Riddle p.printRegion(getRegion(), /*printEntryBlockArgs=*/false);
830fec6c5acSUday Bondhugula }
831fec6c5acSUday Bondhugula
832fec6c5acSUday Bondhugula //===----------------------------------------------------------------------===//
83362828865SStephen Neuendorffer // Test SSACFGRegionOp
83462828865SStephen Neuendorffer //===----------------------------------------------------------------------===//
83562828865SStephen Neuendorffer
getRegionKind(unsigned index)83662828865SStephen Neuendorffer RegionKind SSACFGRegionOp::getRegionKind(unsigned index) {
83762828865SStephen Neuendorffer return RegionKind::SSACFG;
83862828865SStephen Neuendorffer }
83962828865SStephen Neuendorffer
84062828865SStephen Neuendorffer //===----------------------------------------------------------------------===//
84162828865SStephen Neuendorffer // Test GraphRegionOp
84262828865SStephen Neuendorffer //===----------------------------------------------------------------------===//
84362828865SStephen Neuendorffer
getRegionKind(unsigned index)84462828865SStephen Neuendorffer RegionKind GraphRegionOp::getRegionKind(unsigned index) {
84562828865SStephen Neuendorffer return RegionKind::Graph;
84662828865SStephen Neuendorffer }
84762828865SStephen Neuendorffer
84862828865SStephen Neuendorffer //===----------------------------------------------------------------------===//
84957d361bdSUday Bondhugula // Test AffineScopeOp
85048034538SUday Bondhugula //===----------------------------------------------------------------------===//
85148034538SUday Bondhugula
parse(OpAsmParser & parser,OperationState & result)852d7f0083dSRiver Riddle ParseResult AffineScopeOp::parse(OpAsmParser &parser, OperationState &result) {
85348034538SUday Bondhugula // Parse the body region, and reuse the operand info as the argument info.
85448034538SUday Bondhugula Region *body = result.addRegion();
85548034538SUday Bondhugula return parser.parseRegion(*body, /*arguments=*/{}, /*argTypes=*/{});
85648034538SUday Bondhugula }
85748034538SUday Bondhugula
print(OpAsmPrinter & p)858d7f0083dSRiver Riddle void AffineScopeOp::print(OpAsmPrinter &p) {
85957d361bdSUday Bondhugula p << "test.affine_scope ";
860d7f0083dSRiver Riddle p.printRegion(getRegion(), /*printEntryBlockArgs=*/false);
86148034538SUday Bondhugula }
86248034538SUday Bondhugula
86348034538SUday Bondhugula //===----------------------------------------------------------------------===//
864fec6c5acSUday Bondhugula // Test parser.
865fec6c5acSUday Bondhugula //===----------------------------------------------------------------------===//
866fec6c5acSUday Bondhugula
parse(OpAsmParser & parser,OperationState & result)867d7f0083dSRiver Riddle ParseResult ParseIntegerLiteralOp::parse(OpAsmParser &parser,
8686bc9439fSRiver Riddle OperationState &result) {
8696bc9439fSRiver Riddle if (parser.parseOptionalColon())
8706bc9439fSRiver Riddle return success();
8716bc9439fSRiver Riddle uint64_t numResults;
8726bc9439fSRiver Riddle if (parser.parseInteger(numResults))
8736bc9439fSRiver Riddle return failure();
8746bc9439fSRiver Riddle
8756bc9439fSRiver Riddle IndexType type = parser.getBuilder().getIndexType();
8766bc9439fSRiver Riddle for (unsigned i = 0; i < numResults; ++i)
8776bc9439fSRiver Riddle result.addTypes(type);
8786bc9439fSRiver Riddle return success();
8796bc9439fSRiver Riddle }
8806bc9439fSRiver Riddle
print(OpAsmPrinter & p)881d7f0083dSRiver Riddle void ParseIntegerLiteralOp::print(OpAsmPrinter &p) {
882d7f0083dSRiver Riddle if (unsigned numResults = getNumResults())
8836bc9439fSRiver Riddle p << " : " << numResults;
8846bc9439fSRiver Riddle }
8856bc9439fSRiver Riddle
parse(OpAsmParser & parser,OperationState & result)886d7f0083dSRiver Riddle ParseResult ParseWrappedKeywordOp::parse(OpAsmParser &parser,
887fec6c5acSUday Bondhugula OperationState &result) {
888fec6c5acSUday Bondhugula StringRef keyword;
889fec6c5acSUday Bondhugula if (parser.parseKeyword(&keyword))
890fec6c5acSUday Bondhugula return failure();
891fec6c5acSUday Bondhugula result.addAttribute("keyword", parser.getBuilder().getStringAttr(keyword));
892fec6c5acSUday Bondhugula return success();
893fec6c5acSUday Bondhugula }
894fec6c5acSUday Bondhugula
print(OpAsmPrinter & p)895d7f0083dSRiver Riddle void ParseWrappedKeywordOp::print(OpAsmPrinter &p) { p << " " << getKeyword(); }
896fec6c5acSUday Bondhugula
897fec6c5acSUday Bondhugula //===----------------------------------------------------------------------===//
898fec6c5acSUday Bondhugula // Test WrapRegionOp - wrapping op exercising `parseGenericOperation()`.
899fec6c5acSUday Bondhugula
parse(OpAsmParser & parser,OperationState & result)900d7f0083dSRiver Riddle ParseResult WrappingRegionOp::parse(OpAsmParser &parser,
901fec6c5acSUday Bondhugula OperationState &result) {
902fec6c5acSUday Bondhugula if (parser.parseKeyword("wraps"))
903fec6c5acSUday Bondhugula return failure();
904fec6c5acSUday Bondhugula
905fec6c5acSUday Bondhugula // Parse the wrapped op in a region
906fec6c5acSUday Bondhugula Region &body = *result.addRegion();
907fec6c5acSUday Bondhugula body.push_back(new Block);
908fec6c5acSUday Bondhugula Block &block = body.back();
90902b6fb21SMehdi Amini Operation *wrappedOp = parser.parseGenericOperation(&block, block.begin());
91002b6fb21SMehdi Amini if (!wrappedOp)
911fec6c5acSUday Bondhugula return failure();
912fec6c5acSUday Bondhugula
913fec6c5acSUday Bondhugula // Create a return terminator in the inner region, pass as operand to the
914fec6c5acSUday Bondhugula // terminator the returned values from the wrapped operation.
91502b6fb21SMehdi Amini SmallVector<Value, 8> returnOperands(wrappedOp->getResults());
916fb093c83SChris Lattner OpBuilder builder(parser.getContext());
917fec6c5acSUday Bondhugula builder.setInsertionPointToEnd(&block);
91802b6fb21SMehdi Amini builder.create<TestReturnOp>(wrappedOp->getLoc(), returnOperands);
919fec6c5acSUday Bondhugula
920fec6c5acSUday Bondhugula // Get the results type for the wrapping op from the terminator operands.
92102b6fb21SMehdi Amini Operation &returnOp = body.back().back();
92202b6fb21SMehdi Amini result.types.append(returnOp.operand_type_begin(),
92302b6fb21SMehdi Amini returnOp.operand_type_end());
924fec6c5acSUday Bondhugula
925fec6c5acSUday Bondhugula // Use the location of the wrapped op for the "test.wrapping_region" op.
92602b6fb21SMehdi Amini result.location = wrappedOp->getLoc();
927fec6c5acSUday Bondhugula
928fec6c5acSUday Bondhugula return success();
929fec6c5acSUday Bondhugula }
930fec6c5acSUday Bondhugula
print(OpAsmPrinter & p)931d7f0083dSRiver Riddle void WrappingRegionOp::print(OpAsmPrinter &p) {
932c41b16c2SMehdi Amini p << " wraps ";
933d7f0083dSRiver Riddle p.printGenericOp(&getRegion().front().front());
934fec6c5acSUday Bondhugula }
935fec6c5acSUday Bondhugula
936fec6c5acSUday Bondhugula //===----------------------------------------------------------------------===//
937e5a8c8c8SSandeep Dasgupta // Test PrettyPrintedRegionOp - exercising the following parser APIs
938e5a8c8c8SSandeep Dasgupta // parseGenericOperationAfterOpName
939e5a8c8c8SSandeep Dasgupta // parseCustomOperationName
940e5a8c8c8SSandeep Dasgupta //===----------------------------------------------------------------------===//
941e5a8c8c8SSandeep Dasgupta
parse(OpAsmParser & parser,OperationState & result)942d7f0083dSRiver Riddle ParseResult PrettyPrintedRegionOp::parse(OpAsmParser &parser,
943e5a8c8c8SSandeep Dasgupta OperationState &result) {
944e5a8c8c8SSandeep Dasgupta
9456842ec42SRiver Riddle SMLoc loc = parser.getCurrentLocation();
946e5a8c8c8SSandeep Dasgupta Location currLocation = parser.getEncodedSourceLoc(loc);
947e5a8c8c8SSandeep Dasgupta
948e5a8c8c8SSandeep Dasgupta // Parse the operands.
949e13d23bcSMarkus Böck SmallVector<OpAsmParser::UnresolvedOperand, 2> operands;
950e5a8c8c8SSandeep Dasgupta if (parser.parseOperandList(operands))
951e5a8c8c8SSandeep Dasgupta return failure();
952e5a8c8c8SSandeep Dasgupta
953e5a8c8c8SSandeep Dasgupta // Check if we are parsing the pretty-printed version
954e5a8c8c8SSandeep Dasgupta // test.pretty_printed_region start <inner-op> end : <functional-type>
955e5a8c8c8SSandeep Dasgupta // Else fallback to parsing the "non pretty-printed" version.
956e5a8c8c8SSandeep Dasgupta if (!succeeded(parser.parseOptionalKeyword("start")))
957e5a8c8c8SSandeep Dasgupta return parser.parseGenericOperationAfterOpName(
958e5a8c8c8SSandeep Dasgupta result, llvm::makeArrayRef(operands));
959e5a8c8c8SSandeep Dasgupta
960e5a8c8c8SSandeep Dasgupta FailureOr<OperationName> parseOpNameInfo = parser.parseCustomOperationName();
961e5a8c8c8SSandeep Dasgupta if (failed(parseOpNameInfo))
962e5a8c8c8SSandeep Dasgupta return failure();
963e5a8c8c8SSandeep Dasgupta
96414ecafd0SChia-hung Duan StringAttr innerOpName = parseOpNameInfo->getIdentifier();
965e5a8c8c8SSandeep Dasgupta
966e5a8c8c8SSandeep Dasgupta FunctionType opFntype;
967e5a8c8c8SSandeep Dasgupta Optional<Location> explicitLoc;
968e5a8c8c8SSandeep Dasgupta if (parser.parseKeyword("end") || parser.parseColon() ||
969e5a8c8c8SSandeep Dasgupta parser.parseType(opFntype) ||
970e5a8c8c8SSandeep Dasgupta parser.parseOptionalLocationSpecifier(explicitLoc))
971e5a8c8c8SSandeep Dasgupta return failure();
972e5a8c8c8SSandeep Dasgupta
973e5a8c8c8SSandeep Dasgupta // If location of the op is explicitly provided, then use it; Else use
974e5a8c8c8SSandeep Dasgupta // the parser's current location.
97530c67587SKazu Hirata Location opLoc = explicitLoc.value_or(currLocation);
976e5a8c8c8SSandeep Dasgupta
977e5a8c8c8SSandeep Dasgupta // Derive the SSA-values for op's operands.
978e5a8c8c8SSandeep Dasgupta if (parser.resolveOperands(operands, opFntype.getInputs(), loc,
979e5a8c8c8SSandeep Dasgupta result.operands))
980e5a8c8c8SSandeep Dasgupta return failure();
981e5a8c8c8SSandeep Dasgupta
982e5a8c8c8SSandeep Dasgupta // Add a region for op.
983e5a8c8c8SSandeep Dasgupta Region ®ion = *result.addRegion();
984e5a8c8c8SSandeep Dasgupta
985e5a8c8c8SSandeep Dasgupta // Create a basic-block inside op's region.
986e5a8c8c8SSandeep Dasgupta Block &block = region.emplaceBlock();
987e5a8c8c8SSandeep Dasgupta
988e5a8c8c8SSandeep Dasgupta // Create and insert an "inner-op" operation in the block.
989e5a8c8c8SSandeep Dasgupta // Just for testing purposes, we can assume that inner op is a binary op with
990e5a8c8c8SSandeep Dasgupta // result and operand types all same as the test-op's first operand.
991e5a8c8c8SSandeep Dasgupta Type innerOpType = opFntype.getInput(0);
992e5a8c8c8SSandeep Dasgupta Value lhs = block.addArgument(innerOpType, opLoc);
993e5a8c8c8SSandeep Dasgupta Value rhs = block.addArgument(innerOpType, opLoc);
994e5a8c8c8SSandeep Dasgupta
995e5a8c8c8SSandeep Dasgupta OpBuilder builder(parser.getBuilder().getContext());
996e5a8c8c8SSandeep Dasgupta builder.setInsertionPointToStart(&block);
997e5a8c8c8SSandeep Dasgupta
99814ecafd0SChia-hung Duan Operation *innerOp =
99914ecafd0SChia-hung Duan builder.create(opLoc, innerOpName, /*operands=*/{lhs, rhs}, innerOpType);
1000e5a8c8c8SSandeep Dasgupta
1001e5a8c8c8SSandeep Dasgupta // Insert a return statement in the block returning the inner-op's result.
1002e5a8c8c8SSandeep Dasgupta builder.create<TestReturnOp>(innerOp->getLoc(), innerOp->getResults());
1003e5a8c8c8SSandeep Dasgupta
1004e5a8c8c8SSandeep Dasgupta // Populate the op operation-state with result-type and location.
1005e5a8c8c8SSandeep Dasgupta result.addTypes(opFntype.getResults());
1006e5a8c8c8SSandeep Dasgupta result.location = innerOp->getLoc();
1007e5a8c8c8SSandeep Dasgupta
1008e5a8c8c8SSandeep Dasgupta return success();
1009e5a8c8c8SSandeep Dasgupta }
1010e5a8c8c8SSandeep Dasgupta
print(OpAsmPrinter & p)1011d7f0083dSRiver Riddle void PrettyPrintedRegionOp::print(OpAsmPrinter &p) {
1012e5a8c8c8SSandeep Dasgupta p << ' ';
1013d7f0083dSRiver Riddle p.printOperands(getOperands());
1014e5a8c8c8SSandeep Dasgupta
1015d7f0083dSRiver Riddle Operation &innerOp = getRegion().front().front();
1016e5a8c8c8SSandeep Dasgupta // Assuming that region has a single non-terminator inner-op, if the inner-op
1017e5a8c8c8SSandeep Dasgupta // meets some criteria (which in this case is a simple one based on the name
1018e5a8c8c8SSandeep Dasgupta // of inner-op), then we can print the entire region in a succinct way.
1019e5a8c8c8SSandeep Dasgupta // Here we assume that the prototype of "special.op" can be trivially derived
1020e5a8c8c8SSandeep Dasgupta // while parsing it back.
1021e5a8c8c8SSandeep Dasgupta if (innerOp.getName().getStringRef().equals("special.op")) {
1022e5a8c8c8SSandeep Dasgupta p << " start special.op end";
1023e5a8c8c8SSandeep Dasgupta } else {
1024e5a8c8c8SSandeep Dasgupta p << " (";
1025d7f0083dSRiver Riddle p.printRegion(getRegion());
1026e5a8c8c8SSandeep Dasgupta p << ")";
1027e5a8c8c8SSandeep Dasgupta }
1028e5a8c8c8SSandeep Dasgupta
1029e5a8c8c8SSandeep Dasgupta p << " : ";
1030d7f0083dSRiver Riddle p.printFunctionalType(*this);
1031e5a8c8c8SSandeep Dasgupta }
1032e5a8c8c8SSandeep Dasgupta
1033e5a8c8c8SSandeep Dasgupta //===----------------------------------------------------------------------===//
1034fec6c5acSUday Bondhugula // Test PolyForOp - parse list of region arguments.
1035fec6c5acSUday Bondhugula //===----------------------------------------------------------------------===//
1036fec6c5acSUday Bondhugula
parse(OpAsmParser & parser,OperationState & result)1037d7f0083dSRiver Riddle ParseResult PolyForOp::parse(OpAsmParser &parser, OperationState &result) {
1038d85eb4e2SChris Lattner SmallVector<OpAsmParser::Argument, 4> ivsInfo;
1039fec6c5acSUday Bondhugula // Parse list of region arguments without a delimiter.
1040d85eb4e2SChris Lattner if (parser.parseArgumentList(ivsInfo, OpAsmParser::Delimiter::None))
1041fec6c5acSUday Bondhugula return failure();
1042fec6c5acSUday Bondhugula
1043fec6c5acSUday Bondhugula // Parse the body region.
1044fec6c5acSUday Bondhugula Region *body = result.addRegion();
1045d85eb4e2SChris Lattner for (auto &iv : ivsInfo)
1046d85eb4e2SChris Lattner iv.type = parser.getBuilder().getIndexType();
1047d85eb4e2SChris Lattner return parser.parseRegion(*body, ivsInfo);
1048fec6c5acSUday Bondhugula }
1049fec6c5acSUday Bondhugula
print(OpAsmPrinter & p)1050d7f0083dSRiver Riddle void PolyForOp::print(OpAsmPrinter &p) { p.printGenericOp(*this); }
1051d7f0083dSRiver Riddle
getAsmBlockArgumentNames(Region & region,OpAsmSetValueNameFn setNameFn)10527f9e9c7fSMehdi Amini void PolyForOp::getAsmBlockArgumentNames(Region ®ion,
10537f9e9c7fSMehdi Amini OpAsmSetValueNameFn setNameFn) {
10547f9e9c7fSMehdi Amini auto arrayAttr = getOperation()->getAttrOfType<ArrayAttr>("arg_names");
10557f9e9c7fSMehdi Amini if (!arrayAttr)
10567f9e9c7fSMehdi Amini return;
10577f9e9c7fSMehdi Amini auto args = getRegion().front().getArguments();
10587f9e9c7fSMehdi Amini auto e = std::min(arrayAttr.size(), args.size());
10597f9e9c7fSMehdi Amini for (unsigned i = 0; i < e; ++i) {
10607f9e9c7fSMehdi Amini if (auto strAttr = arrayAttr[i].dyn_cast<StringAttr>())
10617f9e9c7fSMehdi Amini setNameFn(args[i], strAttr.getValue());
10627f9e9c7fSMehdi Amini }
10637f9e9c7fSMehdi Amini }
10647f9e9c7fSMehdi Amini
1065fec6c5acSUday Bondhugula //===----------------------------------------------------------------------===//
1066fec6c5acSUday Bondhugula // Test removing op with inner ops.
1067fec6c5acSUday Bondhugula //===----------------------------------------------------------------------===//
1068fec6c5acSUday Bondhugula
1069fec6c5acSUday Bondhugula namespace {
1070fec6c5acSUday Bondhugula struct TestRemoveOpWithInnerOps
1071fec6c5acSUday Bondhugula : public OpRewritePattern<TestOpWithRegionPattern> {
1072fec6c5acSUday Bondhugula using OpRewritePattern<TestOpWithRegionPattern>::OpRewritePattern;
1073fec6c5acSUday Bondhugula
initialize__anonf77d94721411::TestRemoveOpWithInnerOps10740289a269SRiver Riddle void initialize() { setDebugName("TestRemoveOpWithInnerOps"); }
10750289a269SRiver Riddle
matchAndRewrite__anonf77d94721411::TestRemoveOpWithInnerOps1076fec6c5acSUday Bondhugula LogicalResult matchAndRewrite(TestOpWithRegionPattern op,
1077fec6c5acSUday Bondhugula PatternRewriter &rewriter) const override {
1078fec6c5acSUday Bondhugula rewriter.eraseOp(op);
1079fec6c5acSUday Bondhugula return success();
1080fec6c5acSUday Bondhugula }
1081fec6c5acSUday Bondhugula };
1082be0a7e9fSMehdi Amini } // namespace
1083fec6c5acSUday Bondhugula
getCanonicalizationPatterns(RewritePatternSet & results,MLIRContext * context)1084fec6c5acSUday Bondhugula void TestOpWithRegionPattern::getCanonicalizationPatterns(
1085dc4e913bSChris Lattner RewritePatternSet &results, MLIRContext *context) {
1086dc4e913bSChris Lattner results.add<TestRemoveOpWithInnerOps>(context);
1087fec6c5acSUday Bondhugula }
1088fec6c5acSUday Bondhugula
fold(ArrayRef<Attribute> operands)1089fec6c5acSUday Bondhugula OpFoldResult TestOpWithRegionFold::fold(ArrayRef<Attribute> operands) {
10906a994233SJacques Pienaar return getOperand();
1091fec6c5acSUday Bondhugula }
1092fec6c5acSUday Bondhugula
fold(ArrayRef<Attribute> operands)10932bf423b0SRob Suderman OpFoldResult TestOpConstant::fold(ArrayRef<Attribute> operands) {
10942bf423b0SRob Suderman return getValue();
10952bf423b0SRob Suderman }
10962bf423b0SRob Suderman
fold(ArrayRef<Attribute> operands,SmallVectorImpl<OpFoldResult> & results)1097fec6c5acSUday Bondhugula LogicalResult TestOpWithVariadicResultsAndFolder::fold(
1098fec6c5acSUday Bondhugula ArrayRef<Attribute> operands, SmallVectorImpl<OpFoldResult> &results) {
109962bf8509SJacques Pienaar for (Value input : this->getOperands()) {
1100fec6c5acSUday Bondhugula results.push_back(input);
1101fec6c5acSUday Bondhugula }
1102fec6c5acSUday Bondhugula return success();
1103fec6c5acSUday Bondhugula }
1104fec6c5acSUday Bondhugula
fold(ArrayRef<Attribute> operands)110526f93d9fSAlex Zinenko OpFoldResult TestOpInPlaceFold::fold(ArrayRef<Attribute> operands) {
110626f93d9fSAlex Zinenko assert(operands.size() == 1);
110726f93d9fSAlex Zinenko if (operands.front()) {
11081ffc1aaaSChristian Sigg (*this)->setAttr("attr", operands.front());
110926f93d9fSAlex Zinenko return getResult();
111026f93d9fSAlex Zinenko }
111126f93d9fSAlex Zinenko return {};
111226f93d9fSAlex Zinenko }
111326f93d9fSAlex Zinenko
fold(ArrayRef<Attribute> operands)1114a1d5bdf8SMehdi Amini OpFoldResult TestPassthroughFold::fold(ArrayRef<Attribute> operands) {
1115a1d5bdf8SMehdi Amini return getOperand();
1116a1d5bdf8SMehdi Amini }
1117a1d5bdf8SMehdi Amini
inferReturnTypes(MLIRContext *,Optional<Location> location,ValueRange operands,DictionaryAttr attributes,RegionRange regions,SmallVectorImpl<Type> & inferredReturnTypes)111862828865SStephen Neuendorffer LogicalResult OpWithInferTypeInterfaceOp::inferReturnTypes(
1119fec6c5acSUday Bondhugula MLIRContext *, Optional<Location> location, ValueRange operands,
11205eae715aSJacques Pienaar DictionaryAttr attributes, RegionRange regions,
1121fec6c5acSUday Bondhugula SmallVectorImpl<Type> &inferredReturnTypes) {
1122fec6c5acSUday Bondhugula if (operands[0].getType() != operands[1].getType()) {
1123fec6c5acSUday Bondhugula return emitOptionalError(location, "operand type mismatch ",
1124fec6c5acSUday Bondhugula operands[0].getType(), " vs ",
1125fec6c5acSUday Bondhugula operands[1].getType());
1126fec6c5acSUday Bondhugula }
1127fec6c5acSUday Bondhugula inferredReturnTypes.assign({operands[0].getType()});
1128fec6c5acSUday Bondhugula return success();
1129fec6c5acSUday Bondhugula }
1130fec6c5acSUday Bondhugula
1131*c8598fa2SJacques Pienaar // TODO: We should be able to only define either inferReturnType or
1132*c8598fa2SJacques Pienaar // refineReturnType, currently only refineReturnType can be omitted.
inferReturnTypes(MLIRContext * context,Optional<Location> location,ValueRange operands,DictionaryAttr attributes,RegionRange regions,SmallVectorImpl<Type> & returnTypes)1133*c8598fa2SJacques Pienaar LogicalResult OpWithRefineTypeInterfaceOp::inferReturnTypes(
1134*c8598fa2SJacques Pienaar MLIRContext *context, Optional<Location> location, ValueRange operands,
1135*c8598fa2SJacques Pienaar DictionaryAttr attributes, RegionRange regions,
1136*c8598fa2SJacques Pienaar SmallVectorImpl<Type> &returnTypes) {
1137*c8598fa2SJacques Pienaar returnTypes.clear();
1138*c8598fa2SJacques Pienaar return OpWithRefineTypeInterfaceOp::refineReturnTypes(
1139*c8598fa2SJacques Pienaar context, location, operands, attributes, regions, returnTypes);
1140*c8598fa2SJacques Pienaar }
1141*c8598fa2SJacques Pienaar
refineReturnTypes(MLIRContext *,Optional<Location> location,ValueRange operands,DictionaryAttr attributes,RegionRange regions,SmallVectorImpl<Type> & returnTypes)1142*c8598fa2SJacques Pienaar LogicalResult OpWithRefineTypeInterfaceOp::refineReturnTypes(
1143*c8598fa2SJacques Pienaar MLIRContext *, Optional<Location> location, ValueRange operands,
1144*c8598fa2SJacques Pienaar DictionaryAttr attributes, RegionRange regions,
1145*c8598fa2SJacques Pienaar SmallVectorImpl<Type> &returnTypes) {
1146*c8598fa2SJacques Pienaar if (operands[0].getType() != operands[1].getType()) {
1147*c8598fa2SJacques Pienaar return emitOptionalError(location, "operand type mismatch ",
1148*c8598fa2SJacques Pienaar operands[0].getType(), " vs ",
1149*c8598fa2SJacques Pienaar operands[1].getType());
1150*c8598fa2SJacques Pienaar }
1151*c8598fa2SJacques Pienaar // TODO: Add helper to make this more concise to write.
1152*c8598fa2SJacques Pienaar if (returnTypes.empty())
1153*c8598fa2SJacques Pienaar returnTypes.resize(1, nullptr);
1154*c8598fa2SJacques Pienaar if (returnTypes[0] && returnTypes[0] != operands[0].getType())
1155*c8598fa2SJacques Pienaar return emitOptionalError(location,
1156*c8598fa2SJacques Pienaar "required first operand and result to match");
1157*c8598fa2SJacques Pienaar returnTypes[0] = operands[0].getType();
1158*c8598fa2SJacques Pienaar return success();
1159*c8598fa2SJacques Pienaar }
1160*c8598fa2SJacques Pienaar
inferReturnTypeComponents(MLIRContext * context,Optional<Location> location,ValueShapeRange operands,DictionaryAttr attributes,RegionRange regions,SmallVectorImpl<ShapedTypeComponents> & inferredReturnShapes)1161fec6c5acSUday Bondhugula LogicalResult OpWithShapedTypeInferTypeInterfaceOp::inferReturnTypeComponents(
1162ee7242c6SJacques Pienaar MLIRContext *context, Optional<Location> location, ValueShapeRange operands,
11635eae715aSJacques Pienaar DictionaryAttr attributes, RegionRange regions,
1164fec6c5acSUday Bondhugula SmallVectorImpl<ShapedTypeComponents> &inferredReturnShapes) {
1165fec6c5acSUday Bondhugula // Create return type consisting of the last element of the first operand.
1166d425f589SJacques Pienaar auto operandType = operands.front().getType();
1167fec6c5acSUday Bondhugula auto sval = operandType.dyn_cast<ShapedType>();
1168fec6c5acSUday Bondhugula if (!sval) {
1169fec6c5acSUday Bondhugula return emitOptionalError(location, "only shaped type operands allowed");
1170fec6c5acSUday Bondhugula }
1171fec6c5acSUday Bondhugula int64_t dim =
1172fec6c5acSUday Bondhugula sval.hasRank() ? sval.getShape().front() : ShapedType::kDynamicSize;
11731b97cdf8SRiver Riddle auto type = IntegerType::get(context, 17);
1174fec6c5acSUday Bondhugula inferredReturnShapes.push_back(ShapedTypeComponents({dim}, type));
1175fec6c5acSUday Bondhugula return success();
1176fec6c5acSUday Bondhugula }
1177fec6c5acSUday Bondhugula
reifyReturnTypeShapes(OpBuilder & builder,ValueRange operands,llvm::SmallVectorImpl<Value> & shapes)1178fec6c5acSUday Bondhugula LogicalResult OpWithShapedTypeInferTypeInterfaceOp::reifyReturnTypeShapes(
1179851d02f6SWenyi Zhao OpBuilder &builder, ValueRange operands,
1180851d02f6SWenyi Zhao llvm::SmallVectorImpl<Value> &shapes) {
1181fec6c5acSUday Bondhugula shapes = SmallVector<Value, 1>{
1182c0a6318dSMatthias Springer builder.createOrFold<tensor::DimOp>(getLoc(), operands.front(), 0)};
1183fec6c5acSUday Bondhugula return success();
1184fec6c5acSUday Bondhugula }
1185fec6c5acSUday Bondhugula
reifyReturnTypeShapes(OpBuilder & builder,ValueRange operands,llvm::SmallVectorImpl<Value> & shapes)11863ed3e438SMaheshRavishankar LogicalResult OpWithResultShapeInterfaceOp::reifyReturnTypeShapes(
11873ed3e438SMaheshRavishankar OpBuilder &builder, ValueRange operands,
11883ed3e438SMaheshRavishankar llvm::SmallVectorImpl<Value> &shapes) {
11893ed3e438SMaheshRavishankar Location loc = getLoc();
11903ed3e438SMaheshRavishankar shapes.reserve(operands.size());
11913ed3e438SMaheshRavishankar for (Value operand : llvm::reverse(operands)) {
1192f77e9f87SAlexander Belyaev auto rank = operand.getType().cast<RankedTensorType>().getRank();
1193f77e9f87SAlexander Belyaev auto currShape = llvm::to_vector<4>(
1194f77e9f87SAlexander Belyaev llvm::map_range(llvm::seq<int64_t>(0, rank), [&](int64_t dim) -> Value {
1195c0a6318dSMatthias Springer return builder.createOrFold<tensor::DimOp>(loc, operand, dim);
11963ed3e438SMaheshRavishankar }));
11973ed3e438SMaheshRavishankar shapes.push_back(builder.create<tensor::FromElementsOp>(
1198f77e9f87SAlexander Belyaev getLoc(), RankedTensorType::get({rank}, builder.getIndexType()),
1199f77e9f87SAlexander Belyaev currShape));
12003ed3e438SMaheshRavishankar }
12013ed3e438SMaheshRavishankar return success();
12023ed3e438SMaheshRavishankar }
12033ed3e438SMaheshRavishankar
reifyResultShapes(OpBuilder & builder,ReifiedRankedShapedTypeDims & shapes)12049afc0657SMaheshRavishankar LogicalResult OpWithResultShapePerDimInterfaceOp::reifyResultShapes(
12059afc0657SMaheshRavishankar OpBuilder &builder, ReifiedRankedShapedTypeDims &shapes) {
12063ed3e438SMaheshRavishankar Location loc = getLoc();
12073ed3e438SMaheshRavishankar shapes.reserve(getNumOperands());
12083ed3e438SMaheshRavishankar for (Value operand : llvm::reverse(getOperands())) {
12093ed3e438SMaheshRavishankar auto currShape = llvm::to_vector<4>(llvm::map_range(
12103ed3e438SMaheshRavishankar llvm::seq<int64_t>(
12113ed3e438SMaheshRavishankar 0, operand.getType().cast<RankedTensorType>().getRank()),
12123ed3e438SMaheshRavishankar [&](int64_t dim) -> Value {
1213c0a6318dSMatthias Springer return builder.createOrFold<tensor::DimOp>(loc, operand, dim);
12143ed3e438SMaheshRavishankar }));
12153ed3e438SMaheshRavishankar shapes.emplace_back(std::move(currShape));
12163ed3e438SMaheshRavishankar }
12179b051703SMaheshRavishankar return success();
12189b051703SMaheshRavishankar }
12199b051703SMaheshRavishankar
1220fec6c5acSUday Bondhugula //===----------------------------------------------------------------------===//
1221fec6c5acSUday Bondhugula // Test SideEffect interfaces
1222fec6c5acSUday Bondhugula //===----------------------------------------------------------------------===//
1223fec6c5acSUday Bondhugula
1224fec6c5acSUday Bondhugula namespace {
1225fec6c5acSUday Bondhugula /// A test resource for side effects.
1226fec6c5acSUday Bondhugula struct TestResource : public SideEffects::Resource::Base<TestResource> {
MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID__anonf77d94721711::TestResource12275e50dd04SRiver Riddle MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(TestResource)
12285e50dd04SRiver Riddle
1229fec6c5acSUday Bondhugula StringRef getName() final { return "<Test>"; }
1230fec6c5acSUday Bondhugula };
1231be0a7e9fSMehdi Amini } // namespace
1232fec6c5acSUday Bondhugula
testSideEffectOpGetEffect(Operation * op,SmallVectorImpl<SideEffects::EffectInstance<TestEffects::Effect>> & effects)1233d905c103SMehdi Amini static void testSideEffectOpGetEffect(
1234d905c103SMehdi Amini Operation *op,
1235d905c103SMehdi Amini SmallVectorImpl<SideEffects::EffectInstance<TestEffects::Effect>>
1236d905c103SMehdi Amini &effects) {
1237d905c103SMehdi Amini auto effectsAttr = op->getAttrOfType<AffineMapAttr>("effect_parameter");
1238d905c103SMehdi Amini if (!effectsAttr)
1239d905c103SMehdi Amini return;
1240d905c103SMehdi Amini
1241d905c103SMehdi Amini effects.emplace_back(TestEffects::Concrete::get(), effectsAttr);
1242d905c103SMehdi Amini }
1243d905c103SMehdi Amini
getEffects(SmallVectorImpl<MemoryEffects::EffectInstance> & effects)1244fec6c5acSUday Bondhugula void SideEffectOp::getEffects(
1245fec6c5acSUday Bondhugula SmallVectorImpl<MemoryEffects::EffectInstance> &effects) {
1246fec6c5acSUday Bondhugula // Check for an effects attribute on the op instance.
12470bf4a82aSChristian Sigg ArrayAttr effectsAttr = (*this)->getAttrOfType<ArrayAttr>("effects");
1248fec6c5acSUday Bondhugula if (!effectsAttr)
1249fec6c5acSUday Bondhugula return;
1250fec6c5acSUday Bondhugula
1251fec6c5acSUday Bondhugula // If there is one, it is an array of dictionary attributes that hold
1252fec6c5acSUday Bondhugula // information on the effects of this operation.
1253fec6c5acSUday Bondhugula for (Attribute element : effectsAttr) {
1254fec6c5acSUday Bondhugula DictionaryAttr effectElement = element.cast<DictionaryAttr>();
1255fec6c5acSUday Bondhugula
1256fec6c5acSUday Bondhugula // Get the specific memory effect.
1257fec6c5acSUday Bondhugula MemoryEffects::Effect *effect =
1258cc83dc19SChristian Sigg StringSwitch<MemoryEffects::Effect *>(
1259fec6c5acSUday Bondhugula effectElement.get("effect").cast<StringAttr>().getValue())
1260fec6c5acSUday Bondhugula .Case("allocate", MemoryEffects::Allocate::get())
1261fec6c5acSUday Bondhugula .Case("free", MemoryEffects::Free::get())
1262fec6c5acSUday Bondhugula .Case("read", MemoryEffects::Read::get())
1263fec6c5acSUday Bondhugula .Case("write", MemoryEffects::Write::get());
1264fec6c5acSUday Bondhugula
1265fec6c5acSUday Bondhugula // Check for a non-default resource to use.
1266fec6c5acSUday Bondhugula SideEffects::Resource *resource = SideEffects::DefaultResource::get();
1267fec6c5acSUday Bondhugula if (effectElement.get("test_resource"))
1268fec6c5acSUday Bondhugula resource = TestResource::get();
1269fec6c5acSUday Bondhugula
1270c0958b7bSRiver Riddle // Check for a result to affect.
1271c0958b7bSRiver Riddle if (effectElement.get("on_result"))
1272c0958b7bSRiver Riddle effects.emplace_back(effect, getResult(), resource);
1273c0958b7bSRiver Riddle else if (Attribute ref = effectElement.get("on_reference"))
1274c0958b7bSRiver Riddle effects.emplace_back(effect, ref.cast<SymbolRefAttr>(), resource);
1275c0958b7bSRiver Riddle else
1276c0958b7bSRiver Riddle effects.emplace_back(effect, resource);
1277fec6c5acSUday Bondhugula }
1278fec6c5acSUday Bondhugula }
1279fec6c5acSUday Bondhugula
getEffects(SmallVectorImpl<TestEffects::EffectInstance> & effects)1280052d24afSAlex Zinenko void SideEffectOp::getEffects(
1281052d24afSAlex Zinenko SmallVectorImpl<TestEffects::EffectInstance> &effects) {
1282d905c103SMehdi Amini testSideEffectOpGetEffect(getOperation(), effects);
1283052d24afSAlex Zinenko }
1284052d24afSAlex Zinenko
1285fec6c5acSUday Bondhugula //===----------------------------------------------------------------------===//
1286fec6c5acSUday Bondhugula // StringAttrPrettyNameOp
1287fec6c5acSUday Bondhugula //===----------------------------------------------------------------------===//
1288fec6c5acSUday Bondhugula
1289fec6c5acSUday Bondhugula // This op has fancy handling of its SSA result name.
parse(OpAsmParser & parser,OperationState & result)1290d7f0083dSRiver Riddle ParseResult StringAttrPrettyNameOp::parse(OpAsmParser &parser,
1291fec6c5acSUday Bondhugula OperationState &result) {
1292fec6c5acSUday Bondhugula // Add the result types.
1293fec6c5acSUday Bondhugula for (size_t i = 0, e = parser.getNumResults(); i != e; ++i)
1294fec6c5acSUday Bondhugula result.addTypes(parser.getBuilder().getIntegerType(32));
1295fec6c5acSUday Bondhugula
1296fec6c5acSUday Bondhugula if (parser.parseOptionalAttrDictWithKeyword(result.attributes))
1297fec6c5acSUday Bondhugula return failure();
1298fec6c5acSUday Bondhugula
1299fec6c5acSUday Bondhugula // If the attribute dictionary contains no 'names' attribute, infer it from
1300fec6c5acSUday Bondhugula // the SSA name (if specified).
1301fec6c5acSUday Bondhugula bool hadNames = llvm::any_of(result.attributes, [](NamedAttribute attr) {
13020c7890c8SRiver Riddle return attr.getName() == "names";
1303fec6c5acSUday Bondhugula });
1304fec6c5acSUday Bondhugula
1305fec6c5acSUday Bondhugula // If there was no name specified, check to see if there was a useful name
1306fec6c5acSUday Bondhugula // specified in the asm file.
1307fec6c5acSUday Bondhugula if (hadNames || parser.getNumResults() == 0)
1308fec6c5acSUday Bondhugula return success();
1309fec6c5acSUday Bondhugula
1310fec6c5acSUday Bondhugula SmallVector<StringRef, 4> names;
1311fec6c5acSUday Bondhugula auto *context = result.getContext();
1312fec6c5acSUday Bondhugula
1313fec6c5acSUday Bondhugula for (size_t i = 0, e = parser.getNumResults(); i != e; ++i) {
1314fec6c5acSUday Bondhugula auto resultName = parser.getResultName(i);
1315fec6c5acSUday Bondhugula StringRef nameStr;
1316fec6c5acSUday Bondhugula if (!resultName.first.empty() && !isdigit(resultName.first[0]))
1317fec6c5acSUday Bondhugula nameStr = resultName.first;
1318fec6c5acSUday Bondhugula
1319fec6c5acSUday Bondhugula names.push_back(nameStr);
1320fec6c5acSUday Bondhugula }
1321fec6c5acSUday Bondhugula
1322fec6c5acSUday Bondhugula auto namesAttr = parser.getBuilder().getStrArrayAttr(names);
1323195730a6SRiver Riddle result.attributes.push_back({StringAttr::get(context, "names"), namesAttr});
1324fec6c5acSUday Bondhugula return success();
1325fec6c5acSUday Bondhugula }
1326fec6c5acSUday Bondhugula
print(OpAsmPrinter & p)1327d7f0083dSRiver Riddle void StringAttrPrettyNameOp::print(OpAsmPrinter &p) {
1328fec6c5acSUday Bondhugula // Note that we only need to print the "name" attribute if the asmprinter
1329fec6c5acSUday Bondhugula // result name disagrees with it. This can happen in strange cases, e.g.
1330fec6c5acSUday Bondhugula // when there are conflicts.
1331d7f0083dSRiver Riddle bool namesDisagree = getNames().size() != getNumResults();
1332fec6c5acSUday Bondhugula
1333fec6c5acSUday Bondhugula SmallString<32> resultNameStr;
1334d7f0083dSRiver Riddle for (size_t i = 0, e = getNumResults(); i != e && !namesDisagree; ++i) {
1335fec6c5acSUday Bondhugula resultNameStr.clear();
1336fec6c5acSUday Bondhugula llvm::raw_svector_ostream tmpStream(resultNameStr);
1337d7f0083dSRiver Riddle p.printOperand(getResult(i), tmpStream);
1338fec6c5acSUday Bondhugula
1339d7f0083dSRiver Riddle auto expectedName = getNames()[i].dyn_cast<StringAttr>();
1340fec6c5acSUday Bondhugula if (!expectedName ||
1341fec6c5acSUday Bondhugula tmpStream.str().drop_front() != expectedName.getValue()) {
1342fec6c5acSUday Bondhugula namesDisagree = true;
1343fec6c5acSUday Bondhugula }
1344fec6c5acSUday Bondhugula }
1345fec6c5acSUday Bondhugula
1346fec6c5acSUday Bondhugula if (namesDisagree)
1347d7f0083dSRiver Riddle p.printOptionalAttrDictWithKeyword((*this)->getAttrs());
1348fec6c5acSUday Bondhugula else
1349d7f0083dSRiver Riddle p.printOptionalAttrDictWithKeyword((*this)->getAttrs(), {"names"});
1350fec6c5acSUday Bondhugula }
1351fec6c5acSUday Bondhugula
1352fec6c5acSUday Bondhugula // We set the SSA name in the asm syntax to the contents of the name
1353fec6c5acSUday Bondhugula // attribute.
getAsmResultNames(function_ref<void (Value,StringRef)> setNameFn)1354fec6c5acSUday Bondhugula void StringAttrPrettyNameOp::getAsmResultNames(
1355fec6c5acSUday Bondhugula function_ref<void(Value, StringRef)> setNameFn) {
1356fec6c5acSUday Bondhugula
13576a994233SJacques Pienaar auto value = getNames();
1358fec6c5acSUday Bondhugula for (size_t i = 0, e = value.size(); i != e; ++i)
1359fec6c5acSUday Bondhugula if (auto str = value[i].dyn_cast<StringAttr>())
1360fec6c5acSUday Bondhugula if (!str.getValue().empty())
1361fec6c5acSUday Bondhugula setNameFn(getResult(i), str.getValue());
1362fec6c5acSUday Bondhugula }
1363fec6c5acSUday Bondhugula
getAsmResultNames(function_ref<void (Value,StringRef)> setNameFn)13643e8560f8Scpillmayer void CustomResultsNameOp::getAsmResultNames(
13653e8560f8Scpillmayer function_ref<void(Value, StringRef)> setNameFn) {
13663e8560f8Scpillmayer ArrayAttr value = getNames();
13673e8560f8Scpillmayer for (size_t i = 0, e = value.size(); i != e; ++i)
13683e8560f8Scpillmayer if (auto str = value[i].dyn_cast<StringAttr>())
13693e8560f8Scpillmayer if (!str.getValue().empty())
13703e8560f8Scpillmayer setNameFn(getResult(i), str.getValue());
13713e8560f8Scpillmayer }
13723e8560f8Scpillmayer
1373fec6c5acSUday Bondhugula //===----------------------------------------------------------------------===//
137442e5f1d9SRiver Riddle // ResultTypeWithTraitOp
137542e5f1d9SRiver Riddle //===----------------------------------------------------------------------===//
137642e5f1d9SRiver Riddle
verify()137742e5f1d9SRiver Riddle LogicalResult ResultTypeWithTraitOp::verify() {
137842e5f1d9SRiver Riddle if ((*this)->getResultTypes()[0].hasTrait<TypeTrait::TestTypeTrait>())
137942e5f1d9SRiver Riddle return success();
138042e5f1d9SRiver Riddle return emitError("result type should have trait 'TestTypeTrait'");
138142e5f1d9SRiver Riddle }
138242e5f1d9SRiver Riddle
138342e5f1d9SRiver Riddle //===----------------------------------------------------------------------===//
138442e5f1d9SRiver Riddle // AttrWithTraitOp
138542e5f1d9SRiver Riddle //===----------------------------------------------------------------------===//
138642e5f1d9SRiver Riddle
verify()138742e5f1d9SRiver Riddle LogicalResult AttrWithTraitOp::verify() {
138842e5f1d9SRiver Riddle if (getAttr().hasTrait<AttributeTrait::TestAttrTrait>())
138942e5f1d9SRiver Riddle return success();
139042e5f1d9SRiver Riddle return emitError("'attr' attribute should have trait 'TestAttrTrait'");
139142e5f1d9SRiver Riddle }
139242e5f1d9SRiver Riddle
139342e5f1d9SRiver Riddle //===----------------------------------------------------------------------===//
13946f5da84fSMarcel Koester // RegionIfOp
13956f5da84fSMarcel Koester //===----------------------------------------------------------------------===//
13966f5da84fSMarcel Koester
print(OpAsmPrinter & p)1397d7f0083dSRiver Riddle void RegionIfOp::print(OpAsmPrinter &p) {
1398c41b16c2SMehdi Amini p << " ";
1399d7f0083dSRiver Riddle p.printOperands(getOperands());
1400d7f0083dSRiver Riddle p << ": " << getOperandTypes();
1401d7f0083dSRiver Riddle p.printArrowTypeList(getResultTypes());
14026f5da84fSMarcel Koester p << " then ";
1403d7f0083dSRiver Riddle p.printRegion(getThenRegion(),
14046f5da84fSMarcel Koester /*printEntryBlockArgs=*/true,
14056f5da84fSMarcel Koester /*printBlockTerminators=*/true);
14066f5da84fSMarcel Koester p << " else ";
1407d7f0083dSRiver Riddle p.printRegion(getElseRegion(),
14086f5da84fSMarcel Koester /*printEntryBlockArgs=*/true,
14096f5da84fSMarcel Koester /*printBlockTerminators=*/true);
14106f5da84fSMarcel Koester p << " join ";
1411d7f0083dSRiver Riddle p.printRegion(getJoinRegion(),
14126f5da84fSMarcel Koester /*printEntryBlockArgs=*/true,
14136f5da84fSMarcel Koester /*printBlockTerminators=*/true);
14146f5da84fSMarcel Koester }
14156f5da84fSMarcel Koester
parse(OpAsmParser & parser,OperationState & result)1416d7f0083dSRiver Riddle ParseResult RegionIfOp::parse(OpAsmParser &parser, OperationState &result) {
1417e13d23bcSMarkus Böck SmallVector<OpAsmParser::UnresolvedOperand, 2> operandInfos;
14186f5da84fSMarcel Koester SmallVector<Type, 2> operandTypes;
14196f5da84fSMarcel Koester
14206f5da84fSMarcel Koester result.regions.reserve(3);
14216f5da84fSMarcel Koester Region *thenRegion = result.addRegion();
14226f5da84fSMarcel Koester Region *elseRegion = result.addRegion();
14236f5da84fSMarcel Koester Region *joinRegion = result.addRegion();
14246f5da84fSMarcel Koester
14256f5da84fSMarcel Koester // Parse operand, type and arrow type lists.
14266f5da84fSMarcel Koester if (parser.parseOperandList(operandInfos) ||
14276f5da84fSMarcel Koester parser.parseColonTypeList(operandTypes) ||
14286f5da84fSMarcel Koester parser.parseArrowTypeList(result.types))
14296f5da84fSMarcel Koester return failure();
14306f5da84fSMarcel Koester
14316f5da84fSMarcel Koester // Parse all attached regions.
14326f5da84fSMarcel Koester if (parser.parseKeyword("then") || parser.parseRegion(*thenRegion, {}, {}) ||
14336f5da84fSMarcel Koester parser.parseKeyword("else") || parser.parseRegion(*elseRegion, {}, {}) ||
14346f5da84fSMarcel Koester parser.parseKeyword("join") || parser.parseRegion(*joinRegion, {}, {}))
14356f5da84fSMarcel Koester return failure();
14366f5da84fSMarcel Koester
14376f5da84fSMarcel Koester return parser.resolveOperands(operandInfos, operandTypes,
14386f5da84fSMarcel Koester parser.getCurrentLocation(), result.operands);
14396f5da84fSMarcel Koester }
14406f5da84fSMarcel Koester
getSuccessorEntryOperands(Optional<unsigned> index)1441537f2208SMogball OperandRange RegionIfOp::getSuccessorEntryOperands(Optional<unsigned> index) {
1442537f2208SMogball assert(index && *index < 2 && "invalid region index");
14436f5da84fSMarcel Koester return getOperands();
14446f5da84fSMarcel Koester }
14456f5da84fSMarcel Koester
getSuccessorRegions(Optional<unsigned> index,ArrayRef<Attribute> operands,SmallVectorImpl<RegionSuccessor> & regions)14466f5da84fSMarcel Koester void RegionIfOp::getSuccessorRegions(
14476f5da84fSMarcel Koester Optional<unsigned> index, ArrayRef<Attribute> operands,
14486f5da84fSMarcel Koester SmallVectorImpl<RegionSuccessor> ®ions) {
14496f5da84fSMarcel Koester // We always branch to the join region.
1450491d2701SKazu Hirata if (index.has_value()) {
1451c27d8152SKazu Hirata if (index.value() < 2)
14526a994233SJacques Pienaar regions.push_back(RegionSuccessor(&getJoinRegion(), getJoinArgs()));
14536f5da84fSMarcel Koester else
14546f5da84fSMarcel Koester regions.push_back(RegionSuccessor(getResults()));
14556f5da84fSMarcel Koester return;
14566f5da84fSMarcel Koester }
14576f5da84fSMarcel Koester
14586f5da84fSMarcel Koester // The then and else regions are the entry regions of this op.
14596a994233SJacques Pienaar regions.push_back(RegionSuccessor(&getThenRegion(), getThenArgs()));
14606a994233SJacques Pienaar regions.push_back(RegionSuccessor(&getElseRegion(), getElseArgs()));
1461572fa964SMogball }
1462572fa964SMogball
getRegionInvocationBounds(ArrayRef<Attribute> operands,SmallVectorImpl<InvocationBounds> & invocationBounds)1463572fa964SMogball void RegionIfOp::getRegionInvocationBounds(
1464572fa964SMogball ArrayRef<Attribute> operands,
1465572fa964SMogball SmallVectorImpl<InvocationBounds> &invocationBounds) {
1466572fa964SMogball // Each region is invoked at most once.
1467572fa964SMogball invocationBounds.assign(/*NumElts=*/3, /*Elt=*/{0, 1});
1468572fa964SMogball }
1469572fa964SMogball
1470572fa964SMogball //===----------------------------------------------------------------------===//
1471572fa964SMogball // AnyCondOp
1472572fa964SMogball //===----------------------------------------------------------------------===//
1473572fa964SMogball
getSuccessorRegions(Optional<unsigned> index,ArrayRef<Attribute> operands,SmallVectorImpl<RegionSuccessor> & regions)1474572fa964SMogball void AnyCondOp::getSuccessorRegions(Optional<unsigned> index,
1475572fa964SMogball ArrayRef<Attribute> operands,
1476572fa964SMogball SmallVectorImpl<RegionSuccessor> ®ions) {
1477572fa964SMogball // The parent op branches into the only region, and the region branches back
1478572fa964SMogball // to the parent op.
1479537f2208SMogball if (!index)
1480572fa964SMogball regions.emplace_back(&getRegion());
1481572fa964SMogball else
1482572fa964SMogball regions.emplace_back(getResults());
1483572fa964SMogball }
1484572fa964SMogball
getRegionInvocationBounds(ArrayRef<Attribute> operands,SmallVectorImpl<InvocationBounds> & invocationBounds)1485572fa964SMogball void AnyCondOp::getRegionInvocationBounds(
1486572fa964SMogball ArrayRef<Attribute> operands,
1487572fa964SMogball SmallVectorImpl<InvocationBounds> &invocationBounds) {
1488572fa964SMogball invocationBounds.emplace_back(1, 1);
14896f5da84fSMarcel Koester }
14906f5da84fSMarcel Koester
14914694097dSLei Zhang //===----------------------------------------------------------------------===//
14924694097dSLei Zhang // SingleNoTerminatorCustomAsmOp
14934694097dSLei Zhang //===----------------------------------------------------------------------===//
14944694097dSLei Zhang
parse(OpAsmParser & parser,OperationState & state)1495d7f0083dSRiver Riddle ParseResult SingleNoTerminatorCustomAsmOp::parse(OpAsmParser &parser,
14964694097dSLei Zhang OperationState &state) {
14974694097dSLei Zhang Region *body = state.addRegion();
14984694097dSLei Zhang if (parser.parseRegion(*body, /*arguments=*/{}, /*argTypes=*/{}))
14994694097dSLei Zhang return failure();
15004694097dSLei Zhang return success();
15014694097dSLei Zhang }
15024694097dSLei Zhang
print(OpAsmPrinter & printer)1503d7f0083dSRiver Riddle void SingleNoTerminatorCustomAsmOp::print(OpAsmPrinter &printer) {
15044694097dSLei Zhang printer.printRegion(
1505d7f0083dSRiver Riddle getRegion(), /*printEntryBlockArgs=*/false,
15064694097dSLei Zhang // This op has a single block without terminators. But explicitly mark
15074694097dSLei Zhang // as not printing block terminators for testing.
15084694097dSLei Zhang /*printBlockTerminators=*/false);
15094694097dSLei Zhang }
15104694097dSLei Zhang
15115232c5c5SChia-hung Duan //===----------------------------------------------------------------------===//
15125232c5c5SChia-hung Duan // TestVerifiersOp
15135232c5c5SChia-hung Duan //===----------------------------------------------------------------------===//
15145232c5c5SChia-hung Duan
verify()15155232c5c5SChia-hung Duan LogicalResult TestVerifiersOp::verify() {
15165232c5c5SChia-hung Duan if (!getRegion().hasOneBlock())
15175232c5c5SChia-hung Duan return emitOpError("`hasOneBlock` trait hasn't been verified");
15185232c5c5SChia-hung Duan
15195232c5c5SChia-hung Duan Operation *definingOp = getInput().getDefiningOp();
15205232c5c5SChia-hung Duan if (definingOp && failed(mlir::verify(definingOp)))
15215232c5c5SChia-hung Duan return emitOpError("operand hasn't been verified");
15225232c5c5SChia-hung Duan
15235232c5c5SChia-hung Duan emitRemark("success run of verifier");
15245232c5c5SChia-hung Duan
15255232c5c5SChia-hung Duan return success();
15265232c5c5SChia-hung Duan }
15275232c5c5SChia-hung Duan
verifyRegions()15285232c5c5SChia-hung Duan LogicalResult TestVerifiersOp::verifyRegions() {
15295232c5c5SChia-hung Duan if (!getRegion().hasOneBlock())
15305232c5c5SChia-hung Duan return emitOpError("`hasOneBlock` trait hasn't been verified");
15315232c5c5SChia-hung Duan
15325232c5c5SChia-hung Duan for (Block &block : getRegion())
15335232c5c5SChia-hung Duan for (Operation &op : block)
15345232c5c5SChia-hung Duan if (failed(mlir::verify(&op)))
15355232c5c5SChia-hung Duan return emitOpError("nested op hasn't been verified");
15365232c5c5SChia-hung Duan
15375232c5c5SChia-hung Duan emitRemark("success run of region verifier");
15385232c5c5SChia-hung Duan
15395232c5c5SChia-hung Duan return success();
15405232c5c5SChia-hung Duan }
15415232c5c5SChia-hung Duan
154295aff23eSKrzysztof Drewniak //===----------------------------------------------------------------------===//
154395aff23eSKrzysztof Drewniak // Test InferIntRangeInterface
154495aff23eSKrzysztof Drewniak //===----------------------------------------------------------------------===//
154595aff23eSKrzysztof Drewniak
inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,SetIntRangeFn setResultRanges)154695aff23eSKrzysztof Drewniak void TestWithBoundsOp::inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,
154795aff23eSKrzysztof Drewniak SetIntRangeFn setResultRanges) {
154895aff23eSKrzysztof Drewniak setResultRanges(getResult(), {getUmin(), getUmax(), getSmin(), getSmax()});
154995aff23eSKrzysztof Drewniak }
155095aff23eSKrzysztof Drewniak
parse(OpAsmParser & parser,OperationState & result)155195aff23eSKrzysztof Drewniak ParseResult TestWithBoundsRegionOp::parse(OpAsmParser &parser,
155295aff23eSKrzysztof Drewniak OperationState &result) {
155395aff23eSKrzysztof Drewniak if (parser.parseOptionalAttrDict(result.attributes))
155495aff23eSKrzysztof Drewniak return failure();
155595aff23eSKrzysztof Drewniak
155695aff23eSKrzysztof Drewniak // Parse the input argument
155795aff23eSKrzysztof Drewniak OpAsmParser::Argument argInfo;
155895aff23eSKrzysztof Drewniak argInfo.type = parser.getBuilder().getIndexType();
155995aff23eSKrzysztof Drewniak if (failed(parser.parseArgument(argInfo)))
156095aff23eSKrzysztof Drewniak return failure();
156195aff23eSKrzysztof Drewniak
156295aff23eSKrzysztof Drewniak // Parse the body region, and reuse the operand info as the argument info.
156395aff23eSKrzysztof Drewniak Region *body = result.addRegion();
156495aff23eSKrzysztof Drewniak return parser.parseRegion(*body, argInfo, /*enableNameShadowing=*/false);
156595aff23eSKrzysztof Drewniak }
156695aff23eSKrzysztof Drewniak
print(OpAsmPrinter & p)156795aff23eSKrzysztof Drewniak void TestWithBoundsRegionOp::print(OpAsmPrinter &p) {
156895aff23eSKrzysztof Drewniak p.printOptionalAttrDict((*this)->getAttrs());
156995aff23eSKrzysztof Drewniak p << ' ';
157095aff23eSKrzysztof Drewniak p.printRegionArgument(getRegion().getArgument(0), /*argAttrs=*/{},
157195aff23eSKrzysztof Drewniak /*omitType=*/true);
157295aff23eSKrzysztof Drewniak p << ' ';
157395aff23eSKrzysztof Drewniak p.printRegion(getRegion(), /*printEntryBlockArgs=*/false);
157495aff23eSKrzysztof Drewniak }
157595aff23eSKrzysztof Drewniak
inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,SetIntRangeFn setResultRanges)157695aff23eSKrzysztof Drewniak void TestWithBoundsRegionOp::inferResultRanges(
157795aff23eSKrzysztof Drewniak ArrayRef<ConstantIntRanges> argRanges, SetIntRangeFn setResultRanges) {
157895aff23eSKrzysztof Drewniak Value arg = getRegion().getArgument(0);
157995aff23eSKrzysztof Drewniak setResultRanges(arg, {getUmin(), getUmax(), getSmin(), getSmax()});
158095aff23eSKrzysztof Drewniak }
158195aff23eSKrzysztof Drewniak
inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,SetIntRangeFn setResultRanges)158295aff23eSKrzysztof Drewniak void TestIncrementOp::inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,
158395aff23eSKrzysztof Drewniak SetIntRangeFn setResultRanges) {
158495aff23eSKrzysztof Drewniak const ConstantIntRanges &range = argRanges[0];
158595aff23eSKrzysztof Drewniak APInt one(range.umin().getBitWidth(), 1);
158695aff23eSKrzysztof Drewniak setResultRanges(getResult(),
158795aff23eSKrzysztof Drewniak {range.umin().uadd_sat(one), range.umax().uadd_sat(one),
158895aff23eSKrzysztof Drewniak range.smin().sadd_sat(one), range.smax().sadd_sat(one)});
158995aff23eSKrzysztof Drewniak }
159095aff23eSKrzysztof Drewniak
inferResultRanges(ArrayRef<ConstantIntRanges> argRanges,SetIntRangeFn setResultRanges)159195aff23eSKrzysztof Drewniak void TestReflectBoundsOp::inferResultRanges(
159295aff23eSKrzysztof Drewniak ArrayRef<ConstantIntRanges> argRanges, SetIntRangeFn setResultRanges) {
159395aff23eSKrzysztof Drewniak const ConstantIntRanges &range = argRanges[0];
159495aff23eSKrzysztof Drewniak MLIRContext *ctx = getContext();
159595aff23eSKrzysztof Drewniak Builder b(ctx);
159695aff23eSKrzysztof Drewniak setUminAttr(b.getIndexAttr(range.umin().getZExtValue()));
159795aff23eSKrzysztof Drewniak setUmaxAttr(b.getIndexAttr(range.umax().getZExtValue()));
159895aff23eSKrzysztof Drewniak setSminAttr(b.getIndexAttr(range.smin().getSExtValue()));
159995aff23eSKrzysztof Drewniak setSmaxAttr(b.getIndexAttr(range.smax().getSExtValue()));
160095aff23eSKrzysztof Drewniak setResultRanges(getResult(), range);
160195aff23eSKrzysztof Drewniak }
160295aff23eSKrzysztof Drewniak
1603fec6c5acSUday Bondhugula #include "TestOpEnums.cpp.inc"
1604052d24afSAlex Zinenko #include "TestOpInterfaces.cpp.inc"
16052e2cdd0aSRiver Riddle #include "TestTypeInterfaces.cpp.inc"
1606fec6c5acSUday Bondhugula
1607fec6c5acSUday Bondhugula #define GET_OP_CLASSES
1608fec6c5acSUday Bondhugula #include "TestOps.cpp.inc"
1609