23#include "llvm/ADT/TypeSwitch.h"
43 if (
auto intType = dyn_cast<IntegerType>(type))
44 return intType.getWidth();
45 if (llvm::isa<IndexType>(type))
46 return IndexType::kInternalStorageBitWidth;
48 <<
"expected integer or index type for IntegerAttr, but got: " << type;
53 Type type, FailureOr<APInt> &val) {
54 std::optional<unsigned> bitWidth = getIntegerBitWidth(reader, type);
66 FailureOr<APFloat> &val) {
67 auto ftype = dyn_cast<FloatType>(type);
78 rawStringData.resize(isSplat ? 1 : type.getNumElements());
79 for (StringRef &value : rawStringData)
86 DenseStringElementsAttr attr) {
87 bool isSplat = attr.isSplat();
91 for (StringRef str : attr.getRawStringData())
102enum class AffineExprBytecodeKind : uint64_t {
115enum class AffineMapBytecodeKind :
unsigned {
118 ProjectedPermutation = 2,
126 return AffineExprBytecodeKind::Add;
128 return AffineExprBytecodeKind::Mul;
130 return AffineExprBytecodeKind::Mod;
132 return AffineExprBytecodeKind::FloorDiv;
134 return AffineExprBytecodeKind::CeilDiv;
136 llvm_unreachable(
"not a binary AffineExprKind");
144 case static_cast<uint64_t
>(AffineExprBytecodeKind::Add):
146 case static_cast<uint64_t
>(AffineExprBytecodeKind::Mul):
148 case static_cast<uint64_t
>(AffineExprBytecodeKind::Mod):
150 case static_cast<uint64_t
>(AffineExprBytecodeKind::FloorDiv):
152 case static_cast<uint64_t
>(AffineExprBytecodeKind::CeilDiv):
155 llvm_unreachable(
"not a binary AffineExprBytecodeKind");
169 static WorkItem read() {
return {
false, {}}; }
175 work.push_back(WorkItem::read());
177 while (!work.empty()) {
179 if (work.size() > 128)
180 return reader.
emitError(
"AffineExpr work stack overflow");
182 WorkItem item = work.pop_back_val();
184 if (item.isCombine) {
186 if (operands.size() < 2)
187 return reader.
emitError(
"malformed AffineExpr: operand underflow");
202 case static_cast<uint64_t
>(AffineExprBytecodeKind::DimId): {
209 case static_cast<uint64_t
>(AffineExprBytecodeKind::SymbolId): {
216 case static_cast<uint64_t
>(AffineExprBytecodeKind::Constant): {
223 case static_cast<uint64_t
>(AffineExprBytecodeKind::Add):
224 case static_cast<uint64_t>(AffineExprBytecodeKind::
Mul):
225 case static_cast<uint64_t>(AffineExprBytecodeKind::
Mod):
226 case static_cast<uint64_t>(AffineExprBytecodeKind::
FloorDiv):
227 case static_cast<uint64_t>(AffineExprBytecodeKind::
CeilDiv): {
230 work.push_back(WorkItem::combine(fromBytecodeKind(kind)));
231 work.push_back(WorkItem::read());
232 work.push_back(WorkItem::read());
236 return reader.
emitError(
"unknown AffineExpr kind: ") << kind, failure();
240 if (operands.size() != 1)
241 return reader.
emitError(
"malformed AffineExpr: expected single result"),
244 expr = operands.front();
252 writer.
writeVarInt(
static_cast<uint64_t
>(AffineExprBytecodeKind::DimId));
253 writer.
writeVarInt(cast<AffineDimExpr>(expr).getPosition());
256 writer.
writeVarInt(
static_cast<uint64_t
>(AffineExprBytecodeKind::SymbolId));
257 writer.
writeVarInt(cast<AffineSymbolExpr>(expr).getPosition());
260 writer.
writeVarInt(
static_cast<uint64_t
>(AffineExprBytecodeKind::Constant));
270 auto binExpr = cast<AffineBinaryOpExpr>(expr);
271 writeAffineExpr(writer, binExpr.getLHS());
272 writeAffineExpr(writer, binExpr.getRHS());
298 unsigned mapKind = header & 0x3;
299 unsigned numDims = header >> 2;
302 case static_cast<unsigned>(AffineMapBytecodeKind::Identity):
303 map =
AffineMap::getMultiDimIdentityMap(numDims, context);
306 case static_cast<unsigned>(AffineMapBytecodeKind::Permutation): {
308 for (
unsigned i = 0; i < numDims; ++i) {
318 case static_cast<unsigned>(AffineMapBytecodeKind::ProjectedPermutation): {
323 results.reserve(numResults);
324 for (uint64_t i = 0; i < numResults; ++i) {
334 case static_cast<unsigned>(AffineMapBytecodeKind::General): {
335 uint64_t numSymbols, numResults;
340 results.reserve(numResults);
341 for (uint64_t i = 0; i < numResults; ++i) {
343 if (
failed(readAffineExpr(reader, context, expr)))
345 results.push_back(expr);
352 return reader.
emitError(
"unknown AffineMap kind: ")
353 <<
static_cast<unsigned>(mapKind),
367 static_cast<unsigned>(AffineMapBytecodeKind::Identity));
375 static_cast<unsigned>(AffineMapBytecodeKind::Permutation));
385 static_cast<unsigned>(AffineMapBytecodeKind::ProjectedPermutation));
394 static_cast<unsigned>(AffineMapBytecodeKind::General));
398 writeAffineExpr(writer, expr);
404 switch (lineCols.size()) {
406 return FileLineColRange::get(filename);
408 return FileLineColRange::get(filename, lineCols[0]);
410 return FileLineColRange::get(filename, lineCols[0], lineCols[1]);
412 return FileLineColRange::get(filename, lineCols[0], lineCols[1],
415 return FileLineColRange::get(filename, lineCols[0], lineCols[1],
416 lineCols[2], lineCols[3]);
426 lineCols, [&reader](uint64_t &val) {
return reader.
readVarInt(val); });
431 if (range.getStartLine() == 0 && range.getStartColumn() == 0 &&
432 range.getEndLine() == 0 && range.getEndColumn() == 0) {
436 if (range.getStartColumn() == 0 &&
437 range.getStartLine() == range.getEndLine()) {
444 if (range.getEndColumn() == range.getStartColumn() &&
445 range.getStartLine() == range.getEndLine()) {
451 if (range.getStartLine() == range.getEndLine()) {
471 if (!llvm::isa<DenseElementType>(type.getElementType())) {
472 reader.
emitError() <<
"DenseTypedElementsAttr element type must implement "
473 "DenseElementTypeInterface, but got: "
474 << type.getElementType();
483 if (!type.getElementType().isInteger(1)) {
484 rawData.append(blob.begin(), blob.end());
493 size_t numElements = type.getNumElements();
494 size_t packedSize = llvm::divideCeil(numElements, 8);
497 if (blob.size() == 1 && blob[0] ==
static_cast<char>(~0x00)) {
506 if (blob.size() == packedSize && blob.size() != numElements) {
507 rawData.resize(numElements);
508 for (
size_t i = 0; i < numElements; ++i)
509 rawData[i] = (blob[i / 8] & (1 << (i % 8))) ? 1 : 0;
513 rawData.append(blob.begin(), blob.end());
520 if (attr.getElementType().isInteger(1)) {
528 if (attr.isSplat()) {
530 data[0] = rawData[0] ? ~0x00 : 0x00;
535 size_t numElements = attr.getNumElements();
536 data.resize(llvm::divideCeil(numElements, 8));
538 for (
size_t i = 0; i < numElements; ++i)
540 data[i / 8] |= (1 << (i % 8));
548#include "mlir/IR/BuiltinDialectBytecode.cpp.inc"
551struct BuiltinDialectBytecodeInterface :
public BytecodeDialectInterface {
552 BuiltinDialectBytecodeInterface(Dialect *dialect)
553 : BytecodeDialectInterface(dialect) {}
558 Attribute readAttribute(DialectBytecodeReader &reader)
const override {
562 LogicalResult writeAttribute(Attribute attr,
563 DialectBytecodeWriter &writer)
const override {
564 return ::writeAttribute(attr, writer);
570 Type readType(DialectBytecodeReader &reader)
const override {
574 LogicalResult writeType(Type type,
575 DialectBytecodeWriter &writer)
const override {
576 return ::writeType(type, writer);
582 std::unique_ptr<DialectVersion>
583 parseVersion(StringRef version)
const override {
584 int64_t parsedVersion;
585 if (version.getAsInteger(10, parsedVersion) || parsedVersion < 0 ||
588 return std::make_unique<BuiltinDialectVersion>(parsedVersion);
591 LogicalResult verifyVersion(Operation *topLevelOp,
592 const DialectVersion &version)
const override {
593 if (
static_cast<const BuiltinDialectVersion &
>(version).getVersion() >= 1)
595 WalkResult
result = topLevelOp->
walk([](ModuleOp module) {
596 if (!module.getDltiAttr())
598 module.emitOpError("cannot emit builtin dialect version 0 with a 'dlti' "
602 return failure(
result.wasInterrupted());
605 void writeVersion(DialectBytecodeWriter &writer)
const override {
608 if (succeeded(configVersion)) {
610 static_cast<const BuiltinDialectVersion *
>(*configVersion);
612 if (version->getVersion() > 0)
613 writer.
writeVarInt(
static_cast<uint64_t
>(version->getVersion()));
617 if (
auto version = cast<BuiltinDialect>(getDialect())->getVersion();
618 version && version->getVersion() > 0) {
619 writer.
writeVarInt(
static_cast<uint64_t
>(version->getVersion()));
623 std::unique_ptr<DialectVersion>
624 readVersion(DialectBytecodeReader &reader)
const override {
629 auto dialectVersion = std::make_unique<BuiltinDialectVersion>(version);
632 <<
"reading newer builtin dialect version than supported";
636 return dialectVersion;
642 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.
std::enable_if_t< llvm::function_traits< std::decay_t< FnT > >::num_args==1, RetT > walk(FnT &&callback)
Walk the operation by calling the callback for each nested operation (including this one),...
Instances of the Type class are uniqued, have an immutable identifier and an optional mutable compone...
static WalkResult advance()
static WalkResult interrupt()
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()
int64_t getVersion() const