MLIR  15.0.0git
BuiltinDialect.cpp
Go to the documentation of this file.
1 //===- BuiltinDialect.cpp - MLIR Builtin Dialect --------------------------===//
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 contains the Builtin dialect that contains all of the attributes,
10 // operations, and types that are necessary for the validity of the IR.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "mlir/IR/BuiltinDialect.h"
16 #include "mlir/IR/Builders.h"
17 #include "mlir/IR/BuiltinOps.h"
18 #include "mlir/IR/BuiltinTypes.h"
20 #include "mlir/IR/PatternMatch.h"
21 
22 using namespace mlir;
23 
24 //===----------------------------------------------------------------------===//
25 // Builtin Dialect
26 //===----------------------------------------------------------------------===//
27 
28 #include "mlir/IR/BuiltinDialect.cpp.inc"
29 
30 namespace {
31 struct BuiltinOpAsmDialectInterface : public OpAsmDialectInterface {
33 
34  AliasResult getAlias(Attribute attr, raw_ostream &os) const override {
35  if (attr.isa<AffineMapAttr>()) {
36  os << "map";
37  return AliasResult::OverridableAlias;
38  }
39  if (attr.isa<IntegerSetAttr>()) {
40  os << "set";
41  return AliasResult::OverridableAlias;
42  }
43  if (attr.isa<LocationAttr>()) {
44  os << "loc";
45  return AliasResult::OverridableAlias;
46  }
47  return AliasResult::NoAlias;
48  }
49 
50  AliasResult getAlias(Type type, raw_ostream &os) const final {
51  if (auto tupleType = type.dyn_cast<TupleType>()) {
52  if (tupleType.size() > 16) {
53  os << "tuple";
54  return AliasResult::OverridableAlias;
55  }
56  }
57  return AliasResult::NoAlias;
58  }
59 };
60 } // namespace
61 
62 void BuiltinDialect::initialize() {
63  registerTypes();
64  registerAttributes();
65  registerLocationAttributes();
66  addOperations<
67 #define GET_OP_LIST
68 #include "mlir/IR/BuiltinOps.cpp.inc"
69  >();
70  addInterfaces<BuiltinOpAsmDialectInterface>();
71 }
72 
73 //===----------------------------------------------------------------------===//
74 // ModuleOp
75 //===----------------------------------------------------------------------===//
76 
77 void ModuleOp::build(OpBuilder &builder, OperationState &state,
78  Optional<StringRef> name) {
79  state.addRegion()->emplaceBlock();
80  if (name) {
81  state.attributes.push_back(builder.getNamedAttr(
83  }
84 }
85 
86 /// Construct a module from the given context.
87 ModuleOp ModuleOp::create(Location loc, Optional<StringRef> name) {
88  OpBuilder builder(loc->getContext());
89  return builder.create<ModuleOp>(loc, name);
90 }
91 
92 DataLayoutSpecInterface ModuleOp::getDataLayoutSpec() {
93  // Take the first and only (if present) attribute that implements the
94  // interface. This needs a linear search, but is called only once per data
95  // layout object construction that is used for repeated queries.
96  for (NamedAttribute attr : getOperation()->getAttrs())
97  if (auto spec = attr.getValue().dyn_cast<DataLayoutSpecInterface>())
98  return spec;
99  return {};
100 }
101 
103  // Check that none of the attributes are non-dialect attributes, except for
104  // the symbol related attributes.
105  for (auto attr : (*this)->getAttrs()) {
106  if (!attr.getName().strref().contains('.') &&
107  !llvm::is_contained(
110  attr.getName().strref()))
111  return emitOpError() << "can only contain attributes with "
112  "dialect-prefixed names, found: '"
113  << attr.getName().getValue() << "'";
114  }
115 
116  // Check that there is at most one data layout spec attribute.
117  StringRef layoutSpecAttrName;
118  DataLayoutSpecInterface layoutSpec;
119  for (const NamedAttribute &na : (*this)->getAttrs()) {
120  if (auto spec = na.getValue().dyn_cast<DataLayoutSpecInterface>()) {
121  if (layoutSpec) {
123  emitOpError() << "expects at most one data layout attribute";
124  diag.attachNote() << "'" << layoutSpecAttrName
125  << "' is a data layout attribute";
126  diag.attachNote() << "'" << na.getName().getValue()
127  << "' is a data layout attribute";
128  }
129  layoutSpecAttrName = na.getName().strref();
130  layoutSpec = spec;
131  }
132  }
133 
134  return success();
135 }
136 
137 //===----------------------------------------------------------------------===//
138 // UnrealizedConversionCastOp
139 //===----------------------------------------------------------------------===//
140 
142 UnrealizedConversionCastOp::fold(ArrayRef<Attribute> attrOperands,
143  SmallVectorImpl<OpFoldResult> &foldResults) {
144  OperandRange operands = getInputs();
145  ResultRange results = getOutputs();
146 
147  if (operands.getType() == results.getType()) {
148  foldResults.append(operands.begin(), operands.end());
149  return success();
150  }
151 
152  if (operands.empty())
153  return failure();
154 
155  // Check that the input is a cast with results that all feed into this
156  // operation, and operand types that directly match the result types of this
157  // operation.
158  Value firstInput = operands.front();
159  auto inputOp = firstInput.getDefiningOp<UnrealizedConversionCastOp>();
160  if (!inputOp || inputOp.getResults() != operands ||
161  inputOp.getOperandTypes() != results.getTypes())
162  return failure();
163 
164  // If everything matches up, we can fold the passthrough.
165  foldResults.append(inputOp->operand_begin(), inputOp->operand_end());
166  return success();
167 }
168 
169 bool UnrealizedConversionCastOp::areCastCompatible(TypeRange inputs,
170  TypeRange outputs) {
171  // `UnrealizedConversionCastOp` is agnostic of the input/output types.
172  return true;
173 }
174 
175 //===----------------------------------------------------------------------===//
176 // TableGen'd op method definitions
177 //===----------------------------------------------------------------------===//
178 
179 #define GET_OP_CLASSES
180 #include "mlir/IR/BuiltinOps.cpp.inc"
Include the generated interface declarations.
static std::string diag(llvm::Value &v)
static StringRef getSymbolAttrName()
Return the name of the attribute used for symbol names.
Definition: SymbolTable.h:55
The possible results of an alias query.
Definition: AliasAnalysis.h:26
This class represents a diagnostic that is inflight and set to be reported.
Definition: Diagnostics.h:311
bool isa() const
Definition: Attributes.h:109
static StringRef getVisibilityAttrName()
Return the name of the attribute used for symbol visibility.
Definition: SymbolTable.h:61
Location objects represent source locations information in MLIR.
Definition: Location.h:31
This class implements the result iterators for the Operation class.
NamedAttribute getNamedAttr(StringRef name, Attribute val)
Definition: Builders.cpp:81
DataLayoutSpecInterface getDataLayoutSpec(Operation *op)
Definition: Traits.cpp:26
This class defines the main interface for locations in MLIR and acts as a non-nullable wrapper around...
Definition: Location.h:48
NamedAttribute represents a combination of a name and an Attribute value.
Definition: Attributes.h:144
LogicalResult success(bool isSuccess=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:56
Operation * create(const OperationState &state)
Creates an operation given the fields represented as an OperationState.
Definition: Builders.cpp:380
This class represents an efficient way to signal success or failure.
Definition: LogicalResult.h:26
LogicalResult failure(bool isFailure=true)
Utility function to generate a LogicalResult.
Definition: LogicalResult.h:62
MLIRContext * getContext() const
Return the context this attribute belongs to.
Definition: Attributes.cpp:20
Diagnostic & attachNote(Optional< Location > noteLoc=llvm::None)
Attaches a note to this diagnostic.
Definition: Diagnostics.h:345
Attributes are known-constant values of operations.
Definition: Attributes.h:24
This class provides an abstraction over the various different ranges of value types.
Definition: TypeRange.h:38
This represents an operation in an abstracted form, suitable for use with the builder APIs...
Block & emplaceBlock()
Definition: Region.h:46
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition: Types.h:72
This class represents an instance of an SSA value in the MLIR system, representing a computable value...
Definition: Value.h:85
The two locations do not alias at all.
Definition: AliasAnalysis.h:34
OpAsmDialectInterface(Dialect *dialect)
NamedAttrList attributes
Region * addRegion()
Create a region that should be attached to the operation.
U dyn_cast() const
Definition: Attributes.h:124
Operation * getDefiningOp() const
If this value is the result of an operation, return the operation that defines it.
Definition: Value.cpp:20
This class implements the operand iterators for the Operation class.
LogicalResult verify(Operation *op, bool verifyRecursively=true)
Perform (potentially expensive) checks of invariants, used to detect compiler bugs, on this operation and any nested operations.
Definition: Verifier.cpp:372
This class helps build Operations.
Definition: Builders.h:177
void push_back(NamedAttribute newAttribute)
Add an attribute with the specified name.
StringAttr getStringAttr(const Twine &bytes)
Definition: Builders.cpp:201
type_range getTypes() const