MLIR  21.0.0git
BuiltinDialectBytecode.cpp
Go to the documentation of this file.
1 //===- BuiltinDialectBytecode.cpp - Builtin Bytecode Implementation -------===//
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 
10 #include "AttributeDetail.h"
13 #include "mlir/IR/BuiltinDialect.h"
14 #include "mlir/IR/BuiltinTypes.h"
15 #include "mlir/IR/Diagnostics.h"
17 #include "mlir/IR/Location.h"
18 #include "mlir/Support/LLVM.h"
19 #include "llvm/ADT/TypeSwitch.h"
20 #include <cstdint>
21 
22 using namespace mlir;
23 
24 //===----------------------------------------------------------------------===//
25 // BuiltinDialectBytecodeInterface
26 //===----------------------------------------------------------------------===//
27 
28 namespace {
29 
30 //===----------------------------------------------------------------------===//
31 // Utility functions
32 //===----------------------------------------------------------------------===//
33 
34 // TODO: Move these to separate file.
35 
36 // Returns the bitwidth if known, else return 0.
37 static unsigned getIntegerBitWidth(DialectBytecodeReader &reader, Type type) {
38  if (auto intType = dyn_cast<IntegerType>(type)) {
39  return intType.getWidth();
40  }
41  if (llvm::isa<IndexType>(type)) {
42  return IndexType::kInternalStorageBitWidth;
43  }
44  reader.emitError()
45  << "expected integer or index type for IntegerAttr, but got: " << type;
46  return 0;
47 }
48 
49 static LogicalResult readAPIntWithKnownWidth(DialectBytecodeReader &reader,
50  Type type, FailureOr<APInt> &val) {
51  unsigned bitWidth = getIntegerBitWidth(reader, type);
52  val = reader.readAPIntWithKnownWidth(bitWidth);
53  return val;
54 }
55 
56 static LogicalResult
57 readAPFloatWithKnownSemantics(DialectBytecodeReader &reader, Type type,
58  FailureOr<APFloat> &val) {
59  auto ftype = dyn_cast<FloatType>(type);
60  if (!ftype)
61  return failure();
62  val = reader.readAPFloatWithKnownSemantics(ftype.getFloatSemantics());
63  return success();
64 }
65 
66 LogicalResult
67 readPotentiallySplatString(DialectBytecodeReader &reader, ShapedType type,
68  bool isSplat,
69  SmallVectorImpl<StringRef> &rawStringData) {
70  rawStringData.resize(isSplat ? 1 : type.getNumElements());
71  for (StringRef &value : rawStringData)
72  if (failed(reader.readString(value)))
73  return failure();
74  return success();
75 }
76 
77 static void writePotentiallySplatString(DialectBytecodeWriter &writer,
78  DenseStringElementsAttr attr) {
79  bool isSplat = attr.isSplat();
80  if (isSplat)
81  return writer.writeOwnedString(attr.getRawStringData().front());
82 
83  for (StringRef str : attr.getRawStringData())
84  writer.writeOwnedString(str);
85 }
86 
87 static FileLineColRange getFileLineColRange(MLIRContext *context,
88  StringAttr filename,
89  ArrayRef<uint64_t> lineCols) {
90  switch (lineCols.size()) {
91  case 0:
92  return FileLineColRange::get(filename);
93  case 1:
94  return FileLineColRange::get(filename, lineCols[0]);
95  case 2:
96  return FileLineColRange::get(filename, lineCols[0], lineCols[1]);
97  case 3:
98  return FileLineColRange::get(filename, lineCols[0], lineCols[1],
99  lineCols[2]);
100  case 4:
101  return FileLineColRange::get(filename, lineCols[0], lineCols[1],
102  lineCols[2], lineCols[3]);
103  default:
104  return {};
105  }
106 }
107 
108 static LogicalResult
109 readFileLineColRangeLocs(DialectBytecodeReader &reader,
110  SmallVectorImpl<uint64_t> &lineCols) {
111  return reader.readList(
112  lineCols, [&reader](uint64_t &val) { return reader.readVarInt(val); });
113 }
114 
115 static void writeFileLineColRangeLocs(DialectBytecodeWriter &writer,
116  FileLineColRange range) {
117  if (range.getStartLine() == 0 && range.getStartColumn() == 0 &&
118  range.getEndLine() == 0 && range.getEndColumn() == 0) {
119  writer.writeVarInt(0);
120  return;
121  }
122  if (range.getStartColumn() == 0 &&
123  range.getStartLine() == range.getEndLine()) {
124  writer.writeVarInt(1);
125  writer.writeVarInt(range.getStartLine());
126  return;
127  }
128  // The single file:line:col is handled by other writer, but checked here for
129  // completeness.
130  if (range.getEndColumn() == range.getStartColumn() &&
131  range.getStartLine() == range.getEndLine()) {
132  writer.writeVarInt(2);
133  writer.writeVarInt(range.getStartLine());
134  writer.writeVarInt(range.getStartColumn());
135  return;
136  }
137  if (range.getStartLine() == range.getEndLine()) {
138  writer.writeVarInt(3);
139  writer.writeVarInt(range.getStartLine());
140  writer.writeVarInt(range.getStartColumn());
141  writer.writeVarInt(range.getEndColumn());
142  return;
143  }
144  writer.writeVarInt(4);
145  writer.writeVarInt(range.getStartLine());
146  writer.writeVarInt(range.getStartColumn());
147  writer.writeVarInt(range.getEndLine());
148  writer.writeVarInt(range.getEndColumn());
149 }
150 
151 #include "mlir/IR/BuiltinDialectBytecode.cpp.inc"
152 
153 /// This class implements the bytecode interface for the builtin dialect.
154 struct BuiltinDialectBytecodeInterface : public BytecodeDialectInterface {
155  BuiltinDialectBytecodeInterface(Dialect *dialect)
156  : BytecodeDialectInterface(dialect) {}
157 
158  //===--------------------------------------------------------------------===//
159  // Attributes
160 
161  Attribute readAttribute(DialectBytecodeReader &reader) const override {
162  return ::readAttribute(getContext(), reader);
163  }
164 
165  LogicalResult writeAttribute(Attribute attr,
166  DialectBytecodeWriter &writer) const override {
167  return ::writeAttribute(attr, writer);
168  }
169 
170  //===--------------------------------------------------------------------===//
171  // Types
172 
173  Type readType(DialectBytecodeReader &reader) const override {
174  return ::readType(getContext(), reader);
175  }
176 
177  LogicalResult writeType(Type type,
178  DialectBytecodeWriter &writer) const override {
179  return ::writeType(type, writer);
180  }
181 };
182 } // namespace
183 
184 void builtin_dialect_detail::addBytecodeInterface(BuiltinDialect *dialect) {
185  dialect->addInterfaces<BuiltinDialectBytecodeInterface>();
186 }
static MLIRContext * getContext(OpFoldResult val)
Attributes are known-constant values of operations.
Definition: Attributes.h:25
This class defines a virtual interface for reading a bytecode stream, providing hooks into the byteco...
virtual FailureOr< APInt > readAPIntWithKnownWidth(unsigned bitWidth)=0
Read an APInt that is known to have been encoded with the given width.
virtual LogicalResult readVarInt(uint64_t &result)=0
Read a variable width integer.
virtual InFlightDiagnostic emitError(const Twine &msg={}) const =0
Emit an error to the reader.
virtual FailureOr< APFloat > readAPFloatWithKnownSemantics(const llvm::fltSemantics &semantics)=0
Read an APFloat that is known to have been encoded with the given semantics.
virtual LogicalResult readString(StringRef &result)=0
Read a string from the bytecode.
LogicalResult readList(SmallVectorImpl< T > &result, CallbackFn &&callback)
Read out a list of elements, invoking the provided callback for each element.
This class defines a virtual interface for writing to a bytecode stream, providing hooks into the byt...
virtual void writeVarInt(uint64_t value)=0
Write a variable width integer to the output stream.
virtual void writeOwnedString(StringRef str)=0
Write a string to the bytecode, which is owned by the caller and is guaranteed to not die before the ...
Dialects are groups of MLIR operations, types and attributes, as well as behavior associated with the...
Definition: Dialect.h:38
MLIRContext is the top-level object for a collection of MLIR operations.
Definition: MLIRContext.h:60
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
Definition: Types.h:74
void addBytecodeInterface(BuiltinDialect *dialect)
Add the interfaces necessary for encoding the builtin dialect components in bytecode.
Include the generated interface declarations.
auto get(MLIRContext *context, Ts &&...params)
Helper method that injects context only if needed, this helps unify some of the attribute constructio...