22#include "llvm/ADT/TypeSwitch.h"
42 if (
auto intType = dyn_cast<IntegerType>(type))
43 return intType.getWidth();
44 if (llvm::isa<IndexType>(type))
45 return IndexType::kInternalStorageBitWidth;
47 <<
"expected integer or index type for IntegerAttr, but got: " << type;
52 Type type, FailureOr<APInt> &val) {
53 std::optional<unsigned> bitWidth = getIntegerBitWidth(reader, type);
65 FailureOr<APFloat> &val) {
66 auto ftype = dyn_cast<FloatType>(type);
77 rawStringData.resize(isSplat ? 1 : type.getNumElements());
78 for (StringRef &value : rawStringData)
85 DenseStringElementsAttr attr) {
86 bool isSplat = attr.isSplat();
90 for (StringRef str : attr.getRawStringData())
101enum class AffineExprBytecodeKind : uint64_t {
114enum class AffineMapBytecodeKind :
unsigned {
117 ProjectedPermutation = 2,
125 return AffineExprBytecodeKind::Add;
127 return AffineExprBytecodeKind::Mul;
129 return AffineExprBytecodeKind::Mod;
131 return AffineExprBytecodeKind::FloorDiv;
133 return AffineExprBytecodeKind::CeilDiv;
135 llvm_unreachable(
"not a binary AffineExprKind");
143 case static_cast<uint64_t
>(AffineExprBytecodeKind::Add):
145 case static_cast<uint64_t
>(AffineExprBytecodeKind::Mul):
147 case static_cast<uint64_t
>(AffineExprBytecodeKind::Mod):
149 case static_cast<uint64_t
>(AffineExprBytecodeKind::FloorDiv):
151 case static_cast<uint64_t
>(AffineExprBytecodeKind::CeilDiv):
154 llvm_unreachable(
"not a binary AffineExprBytecodeKind");
168 static WorkItem read() {
return {
false, {}}; }
174 work.push_back(WorkItem::read());
176 while (!work.empty()) {
178 if (work.size() > 128)
179 return reader.
emitError(
"AffineExpr work stack overflow");
181 WorkItem item = work.pop_back_val();
183 if (item.isCombine) {
185 if (operands.size() < 2)
186 return reader.
emitError(
"malformed AffineExpr: operand underflow");
201 case static_cast<uint64_t
>(AffineExprBytecodeKind::DimId): {
208 case static_cast<uint64_t
>(AffineExprBytecodeKind::SymbolId): {
215 case static_cast<uint64_t
>(AffineExprBytecodeKind::Constant): {
222 case static_cast<uint64_t
>(AffineExprBytecodeKind::Add):
223 case static_cast<uint64_t>(AffineExprBytecodeKind::
Mul):
224 case static_cast<uint64_t>(AffineExprBytecodeKind::
Mod):
225 case static_cast<uint64_t>(AffineExprBytecodeKind::
FloorDiv):
226 case static_cast<uint64_t>(AffineExprBytecodeKind::
CeilDiv): {
229 work.push_back(WorkItem::combine(fromBytecodeKind(kind)));
230 work.push_back(WorkItem::read());
231 work.push_back(WorkItem::read());
235 return reader.
emitError(
"unknown AffineExpr kind: ") << kind, failure();
239 if (operands.size() != 1)
240 return reader.
emitError(
"malformed AffineExpr: expected single result"),
243 expr = operands.front();
251 writer.
writeVarInt(
static_cast<uint64_t
>(AffineExprBytecodeKind::DimId));
252 writer.
writeVarInt(cast<AffineDimExpr>(expr).getPosition());
255 writer.
writeVarInt(
static_cast<uint64_t
>(AffineExprBytecodeKind::SymbolId));
256 writer.
writeVarInt(cast<AffineSymbolExpr>(expr).getPosition());
259 writer.
writeVarInt(
static_cast<uint64_t
>(AffineExprBytecodeKind::Constant));
269 auto binExpr = cast<AffineBinaryOpExpr>(expr);
270 writeAffineExpr(writer, binExpr.getLHS());
271 writeAffineExpr(writer, binExpr.getRHS());
297 unsigned mapKind = header & 0x3;
298 unsigned numDims = header >> 2;
301 case static_cast<unsigned>(AffineMapBytecodeKind::Identity):
302 map =
AffineMap::getMultiDimIdentityMap(numDims, context);
305 case static_cast<unsigned>(AffineMapBytecodeKind::Permutation): {
307 for (
unsigned i = 0; i < numDims; ++i) {
317 case static_cast<unsigned>(AffineMapBytecodeKind::ProjectedPermutation): {
322 results.reserve(numResults);
323 for (uint64_t i = 0; i < numResults; ++i) {
333 case static_cast<unsigned>(AffineMapBytecodeKind::General): {
334 uint64_t numSymbols, numResults;
339 results.reserve(numResults);
340 for (uint64_t i = 0; i < numResults; ++i) {
342 if (
failed(readAffineExpr(reader, context, expr)))
344 results.push_back(expr);
351 return reader.
emitError(
"unknown AffineMap kind: ")
352 <<
static_cast<unsigned>(mapKind),
366 static_cast<unsigned>(AffineMapBytecodeKind::Identity));
374 static_cast<unsigned>(AffineMapBytecodeKind::Permutation));
384 static_cast<unsigned>(AffineMapBytecodeKind::ProjectedPermutation));
393 static_cast<unsigned>(AffineMapBytecodeKind::General));
397 writeAffineExpr(writer, expr);
403 switch (lineCols.size()) {
405 return FileLineColRange::get(filename);
407 return FileLineColRange::get(filename, lineCols[0]);
409 return FileLineColRange::get(filename, lineCols[0], lineCols[1]);
411 return FileLineColRange::get(filename, lineCols[0], lineCols[1],
414 return FileLineColRange::get(filename, lineCols[0], lineCols[1],
415 lineCols[2], lineCols[3]);
425 lineCols, [&reader](uint64_t &val) {
return reader.
readVarInt(val); });
430 if (range.getStartLine() == 0 && range.getStartColumn() == 0 &&
431 range.getEndLine() == 0 && range.getEndColumn() == 0) {
435 if (range.getStartColumn() == 0 &&
436 range.getStartLine() == range.getEndLine()) {
443 if (range.getEndColumn() == range.getStartColumn() &&
444 range.getStartLine() == range.getEndLine()) {
450 if (range.getStartLine() == range.getEndLine()) {
470 if (!llvm::isa<DenseElementType>(type.getElementType())) {
471 reader.
emitError() <<
"DenseTypedElementsAttr element type must implement "
472 "DenseElementTypeInterface, but got: "
473 << type.getElementType();
482 if (!type.getElementType().isInteger(1)) {
483 rawData.append(blob.begin(), blob.end());
492 size_t numElements = type.getNumElements();
493 size_t packedSize = llvm::divideCeil(numElements, 8);
496 if (blob.size() == 1 && blob[0] ==
static_cast<char>(~0x00)) {
505 if (blob.size() == packedSize && blob.size() != numElements) {
506 rawData.resize(numElements);
507 for (
size_t i = 0; i < numElements; ++i)
508 rawData[i] = (blob[i / 8] & (1 << (i % 8))) ? 1 : 0;
512 rawData.append(blob.begin(), blob.end());
519 if (attr.getElementType().isInteger(1)) {
527 if (attr.isSplat()) {
529 data[0] = rawData[0] ? ~0x00 : 0x00;
534 size_t numElements = attr.getNumElements();
535 data.resize(llvm::divideCeil(numElements, 8));
537 for (
size_t i = 0; i < numElements; ++i)
539 data[i / 8] |= (1 << (i % 8));
547#include "mlir/IR/BuiltinDialectBytecode.cpp.inc"
550struct BuiltinDialectBytecodeInterface :
public BytecodeDialectInterface {
551 BuiltinDialectBytecodeInterface(Dialect *dialect)
552 : BytecodeDialectInterface(dialect) {}
557 Attribute readAttribute(DialectBytecodeReader &reader)
const override {
561 LogicalResult writeAttribute(Attribute attr,
562 DialectBytecodeWriter &writer)
const override {
563 return ::writeAttribute(attr, writer);
569 Type readType(DialectBytecodeReader &reader)
const override {
573 LogicalResult writeType(Type type,
574 DialectBytecodeWriter &writer)
const override {
575 return ::writeType(type, writer);
581 void writeVersion(DialectBytecodeWriter &writer)
const override {
584 if (succeeded(configVersion)) {
586 static_cast<const BuiltinDialectVersion *
>(*configVersion);
587 writer.
writeVarInt(
static_cast<uint64_t
>(version->getVersion()));
591 if (
auto version = cast<BuiltinDialect>(getDialect())->getVersion();
592 version && version->getVersion() > 0) {
593 writer.
writeVarInt(
static_cast<uint64_t
>(version->getVersion()));
597 std::unique_ptr<DialectVersion>
598 readVersion(DialectBytecodeReader &reader)
const override {
603 auto dialectVersion = std::make_unique<BuiltinDialectVersion>(version);
606 <<
"reading newer builtin dialect version than supported";
610 return dialectVersion;
616 dialect->addInterfaces<BuiltinDialectBytecodeInterface>();
Base type for affine expression.
AffineExprKind getKind() const
Return the classification for this type.
A multi-dimensional affine map Affine map's are immutable like Type's, and they are uniqued.
unsigned getDimPosition(unsigned idx) const
Extracts the position of the dimensional expression at the given result, when the caller knows it is ...
static AffineMap get(MLIRContext *context)
Returns a zero result affine map with no dimensions or symbols: () -> ().
bool isProjectedPermutation(bool allowZeroInResults=false) const
Returns true if the AffineMap represents a subset (i.e.
unsigned getNumSymbols() const
unsigned getNumDims() const
ArrayRef< AffineExpr > getResults() const
unsigned getNumResults() const
static AffineMap getPermutationMap(ArrayRef< unsigned > permutation, MLIRContext *context)
Returns an AffineMap representing a permutation.
bool isIdentity() const
Returns true if this affine map is an identity affine map.
bool isPermutation() const
Returns true if the AffineMap represents a symbol-less permutation map.
This class defines a virtual interface for reading a bytecode stream, providing hooks into the byteco...
virtual LogicalResult readBlob(ArrayRef< char > &result)=0
Read a blob from the bytecode.
virtual LogicalResult readVarInt(uint64_t &result)=0
Read a variable width integer.
virtual FailureOr< APInt > readAPIntWithKnownWidth(unsigned bitWidth)=0
Read an APInt that is known to have been encoded with the given width.
virtual InFlightDiagnostic emitError(const Twine &msg={}) const =0
Emit an error to the reader.
virtual LogicalResult readString(StringRef &result)=0
Read a string from the bytecode.
virtual LogicalResult readSignedVarInt(int64_t &result)=0
Read a signed variable width integer.
LogicalResult readList(SmallVectorImpl< T > &result, CallbackFn &&callback)
Read out a list of elements, invoking the provided callback for each element.
virtual FailureOr< APFloat > readAPFloatWithKnownSemantics(const llvm::fltSemantics &semantics)=0
Read an APFloat that is known to have been encoded with the given semantics.
This class defines a virtual interface for writing to a bytecode stream, providing hooks into the byt...
virtual FailureOr< const DialectVersion * > getDialectVersion(StringRef dialectName) const =0
Retrieve the dialect version by name if available.
virtual void writeVarInt(uint64_t value)=0
Write a variable width integer to the output stream.
virtual void writeUnownedBlob(ArrayRef< char > blob)=0
Write a blob to the bytecode, which is not owned by the caller.
virtual void writeOwnedBlob(ArrayRef< char > blob)=0
Write a blob to the bytecode, which is owned by the caller and is guaranteed to not die before the en...
virtual void writeSignedVarInt(int64_t value)=0
Write a signed 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 ...
MLIRContext is the top-level object for a collection of MLIR operations.
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
void addBytecodeInterface(BuiltinDialect *dialect)
Add the interfaces necessary for encoding the builtin dialect components in bytecode.
OwningOpRef< spirv::ModuleOp > combine(ArrayRef< spirv::ModuleOp > inputModules, OpBuilder &combinedModuleBuilder, SymbolRenameListener symRenameListener)
Combines a list of SPIR-V inputModules into one.
Include the generated interface declarations.
@ CeilDiv
RHS of ceildiv is always a constant or a symbolic expression.
@ Mul
RHS of mul is always a constant or a symbolic expression.
@ Mod
RHS of mod is always a constant or a symbolic expression with a positive value.
@ DimId
Dimensional identifier.
@ FloorDiv
RHS of floordiv is always a constant or a symbolic expression.
@ Constant
Constant integer.
@ SymbolId
Symbolic identifier.
AffineExpr getAffineBinaryOpExpr(AffineExprKind kind, AffineExpr lhs, AffineExpr rhs)
AffineExpr getAffineConstantExpr(int64_t constant, MLIRContext *context)
AffineExpr getAffineDimExpr(unsigned position, MLIRContext *context)
These free functions allow clients of the API to not use classes in detail.
AffineExpr getAffineSymbolExpr(unsigned position, MLIRContext *context)
static BuiltinDialectVersion getCurrentVersion()