21#include "llvm/ADT/TypeSwitch.h"
41 if (
auto intType = dyn_cast<IntegerType>(type))
42 return intType.getWidth();
43 if (llvm::isa<IndexType>(type))
44 return IndexType::kInternalStorageBitWidth;
46 <<
"expected integer or index type for IntegerAttr, but got: " << type;
51 Type type, FailureOr<APInt> &val) {
52 std::optional<unsigned> bitWidth = getIntegerBitWidth(reader, type);
64 FailureOr<APFloat> &val) {
65 auto ftype = dyn_cast<FloatType>(type);
76 rawStringData.resize(isSplat ? 1 : type.getNumElements());
77 for (StringRef &value : rawStringData)
84 DenseStringElementsAttr attr) {
85 bool isSplat = attr.isSplat();
89 for (StringRef str : attr.getRawStringData())
100enum class AffineExprBytecodeKind : uint64_t {
113enum class AffineMapBytecodeKind :
unsigned {
116 ProjectedPermutation = 2,
124 return AffineExprBytecodeKind::Add;
126 return AffineExprBytecodeKind::Mul;
128 return AffineExprBytecodeKind::Mod;
130 return AffineExprBytecodeKind::FloorDiv;
132 return AffineExprBytecodeKind::CeilDiv;
134 llvm_unreachable(
"not a binary AffineExprKind");
142 case static_cast<uint64_t
>(AffineExprBytecodeKind::Add):
144 case static_cast<uint64_t
>(AffineExprBytecodeKind::Mul):
146 case static_cast<uint64_t
>(AffineExprBytecodeKind::Mod):
148 case static_cast<uint64_t
>(AffineExprBytecodeKind::FloorDiv):
150 case static_cast<uint64_t
>(AffineExprBytecodeKind::CeilDiv):
153 llvm_unreachable(
"not a binary AffineExprBytecodeKind");
167 static WorkItem read() {
return {
false, {}}; }
173 work.push_back(WorkItem::read());
175 while (!work.empty()) {
177 if (work.size() > 128)
178 return reader.
emitError(
"AffineExpr work stack overflow"), failure();
180 WorkItem item = work.pop_back_val();
182 if (item.isCombine) {
184 if (operands.size() < 2)
185 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 return operands.front();
250 writer.
writeVarInt(
static_cast<uint64_t
>(AffineExprBytecodeKind::DimId));
251 writer.
writeVarInt(cast<AffineDimExpr>(expr).getPosition());
254 writer.
writeVarInt(
static_cast<uint64_t
>(AffineExprBytecodeKind::SymbolId));
255 writer.
writeVarInt(cast<AffineSymbolExpr>(expr).getPosition());
258 writer.
writeVarInt(
static_cast<uint64_t
>(AffineExprBytecodeKind::Constant));
268 auto binExpr = cast<AffineBinaryOpExpr>(expr);
269 writeAffineExpr(writer, binExpr.getLHS());
270 writeAffineExpr(writer, binExpr.getRHS());
296 unsigned mapKind = header & 0x3;
297 unsigned numDims = header >> 2;
300 case static_cast<unsigned>(AffineMapBytecodeKind::Identity):
301 map =
AffineMap::getMultiDimIdentityMap(numDims, context);
304 case static_cast<unsigned>(AffineMapBytecodeKind::Permutation): {
306 for (
unsigned i = 0; i < numDims; ++i) {
316 case static_cast<unsigned>(AffineMapBytecodeKind::ProjectedPermutation): {
321 results.reserve(numResults);
322 for (uint64_t i = 0; i < numResults; ++i) {
332 case static_cast<unsigned>(AffineMapBytecodeKind::General): {
333 uint64_t numSymbols, numResults;
338 results.reserve(numResults);
339 for (uint64_t i = 0; i < numResults; ++i) {
340 auto expr = readAffineExpr(reader, context);
343 results.push_back(*expr);
350 return reader.
emitError(
"unknown AffineMap kind: ")
351 <<
static_cast<unsigned>(mapKind),
365 static_cast<unsigned>(AffineMapBytecodeKind::Identity));
373 static_cast<unsigned>(AffineMapBytecodeKind::Permutation));
383 static_cast<unsigned>(AffineMapBytecodeKind::ProjectedPermutation));
392 static_cast<unsigned>(AffineMapBytecodeKind::General));
396 writeAffineExpr(writer, expr);
402 switch (lineCols.size()) {
404 return FileLineColRange::get(filename);
406 return FileLineColRange::get(filename, lineCols[0]);
408 return FileLineColRange::get(filename, lineCols[0], lineCols[1]);
410 return FileLineColRange::get(filename, lineCols[0], lineCols[1],
413 return FileLineColRange::get(filename, lineCols[0], lineCols[1],
414 lineCols[2], lineCols[3]);
424 lineCols, [&reader](uint64_t &val) {
return reader.
readVarInt(val); });
429 if (range.getStartLine() == 0 && range.getStartColumn() == 0 &&
430 range.getEndLine() == 0 && range.getEndColumn() == 0) {
434 if (range.getStartColumn() == 0 &&
435 range.getStartLine() == range.getEndLine()) {
442 if (range.getEndColumn() == range.getStartColumn() &&
443 range.getStartLine() == range.getEndLine()) {
449 if (range.getStartLine() == range.getEndLine()) {
469 if (!llvm::isa<DenseElementType>(type.getElementType())) {
470 reader.
emitError() <<
"DenseTypedElementsAttr element type must implement "
471 "DenseElementTypeInterface, but got: "
472 << type.getElementType();
481 if (!type.getElementType().isInteger(1)) {
482 rawData.append(blob.begin(), blob.end());
491 size_t numElements = type.getNumElements();
492 size_t packedSize = llvm::divideCeil(numElements, 8);
495 if (blob.size() == 1 && blob[0] ==
static_cast<char>(~0x00)) {
504 if (blob.size() == packedSize && blob.size() != numElements) {
505 rawData.resize(numElements);
506 for (
size_t i = 0; i < numElements; ++i)
507 rawData[i] = (blob[i / 8] & (1 << (i % 8))) ? 1 : 0;
511 rawData.append(blob.begin(), blob.end());
518 if (attr.getElementType().isInteger(1)) {
526 if (attr.isSplat()) {
528 data[0] = rawData[0] ? ~0x00 : 0x00;
533 size_t numElements = attr.getNumElements();
534 data.resize(llvm::divideCeil(numElements, 8));
536 for (
size_t i = 0; i < numElements; ++i)
538 data[i / 8] |= (1 << (i % 8));
546#include "mlir/IR/BuiltinDialectBytecode.cpp.inc"
549struct BuiltinDialectBytecodeInterface :
public BytecodeDialectInterface {
550 BuiltinDialectBytecodeInterface(Dialect *dialect)
551 : BytecodeDialectInterface(dialect) {}
556 Attribute readAttribute(DialectBytecodeReader &reader)
const override {
560 LogicalResult writeAttribute(Attribute attr,
561 DialectBytecodeWriter &writer)
const override {
562 return ::writeAttribute(attr, writer);
568 Type readType(DialectBytecodeReader &reader)
const override {
572 LogicalResult writeType(Type type,
573 DialectBytecodeWriter &writer)
const override {
574 return ::writeType(type, writer);
580 void writeVersion(DialectBytecodeWriter &writer)
const override {
583 if (succeeded(configVersion)) {
585 static_cast<const BuiltinDialectVersion *
>(*configVersion);
586 writer.
writeVarInt(
static_cast<uint64_t
>(version->getVersion()));
590 if (
auto version = cast<BuiltinDialect>(getDialect())->getVersion();
591 version && version->getVersion() > 0) {
592 writer.
writeVarInt(
static_cast<uint64_t
>(version->getVersion()));
596 std::unique_ptr<DialectVersion>
597 readVersion(DialectBytecodeReader &reader)
const override {
602 auto dialectVersion = std::make_unique<BuiltinDialectVersion>(version);
605 <<
"reading newer builtin dialect version than supported";
609 return dialectVersion;
615 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()