1 //===- Dialect.cpp - Implementation of the linalg dialect and types -------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file implements the Linalg dialect types and dialect.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "mlir/Dialect/Linalg/IR/LinalgTypes.h"
14 #include "mlir/Dialect/Linalg/IR/LinalgOps.h"
15 #include "mlir/IR/BuiltinTypes.h"
16 #include "mlir/IR/Dialect.h"
17 #include "mlir/IR/DialectImplementation.h"
18 #include "mlir/Parser.h"
19 #include "mlir/Support/LLVM.h"
20 #include "mlir/Transforms/InliningUtils.h"
21 
22 #include "llvm/ADT/StringExtras.h"
23 #include "llvm/Support/raw_ostream.h"
24 
25 using namespace mlir;
26 using namespace mlir::linalg;
27 
28 //===----------------------------------------------------------------------===//
29 // LinalgDialect Dialect Interfaces
30 //===----------------------------------------------------------------------===//
31 
32 namespace {
33 
34 struct LinalgInlinerInterface : public DialectInlinerInterface {
35   using DialectInlinerInterface::DialectInlinerInterface;
36 
37   // We don't have any special restrictions on what can be inlined into
38   // destination regions (e.g. while/conditional bodies). Always allow it.
isLegalToInline__anona0004cfa0111::LinalgInlinerInterface39   bool isLegalToInline(Region *dest, Region *src, bool wouldBeCloned,
40                        BlockAndValueMapping &valueMapping) const final {
41     return true;
42   }
43   // Operations in Linalg dialect are always legal to inline.
isLegalToInline__anona0004cfa0111::LinalgInlinerInterface44   bool isLegalToInline(Operation *, Region *, bool,
45                        BlockAndValueMapping &) const final {
46     return true;
47   }
48   // Handle the given inlined terminator by replacing it with a new operation
49   // as necessary. Required when the region has only one block.
handleTerminator__anona0004cfa0111::LinalgInlinerInterface50   void handleTerminator(Operation *op,
51                         ArrayRef<Value> valuesToRepl) const final {}
52 };
53 
54 } // end anonymous namespace
55 
56 //===----------------------------------------------------------------------===//
57 // LinalgDialect
58 //===----------------------------------------------------------------------===//
59 
initialize()60 void mlir::linalg::LinalgDialect::initialize() {
61   getContext()->getOrLoadDialect("std");
62 
63   addTypes<RangeType>();
64   addOperations<
65 #define GET_OP_LIST
66 #include "mlir/Dialect/Linalg/IR/LinalgOps.cpp.inc"
67       >();
68   addOperations<
69 #define GET_OP_LIST
70 #include "mlir/Dialect/Linalg/IR/LinalgStructuredOps.cpp.inc"
71       >();
72 
73   addInterfaces<LinalgInlinerInterface>();
74 }
75 
parseType(DialectAsmParser & parser) const76 Type mlir::linalg::LinalgDialect::parseType(DialectAsmParser &parser) const {
77   // Parse the main keyword for the type.
78   StringRef keyword;
79   if (parser.parseKeyword(&keyword))
80     return Type();
81   MLIRContext *context = getContext();
82 
83   // Handle 'range' types.
84   if (keyword == "range")
85     return RangeType::get(context);
86 
87   parser.emitError(parser.getNameLoc(), "unknown Linalg type: " + keyword);
88   return Type();
89 }
90 
91 /// RangeType prints as just "range".
print(RangeType rt,DialectAsmPrinter & os)92 static void print(RangeType rt, DialectAsmPrinter &os) { os << "range"; }
93 
printType(Type type,DialectAsmPrinter & os) const94 void mlir::linalg::LinalgDialect::printType(Type type,
95                                             DialectAsmPrinter &os) const {
96   print(type.cast<RangeType>(), os);
97 }
98