diff --git a/mlir/include/mlir/Bytecode/Encoding.h b/mlir/include/mlir/Bytecode/Encoding.h --- a/mlir/include/mlir/Bytecode/Encoding.h +++ b/mlir/include/mlir/Bytecode/Encoding.h @@ -28,6 +28,23 @@ /// The minimum supported version of the bytecode. kMinSupportedVersion = 0, + /// Dialects versioning was added in version 1. + kDialectVersioning = 1, + + /// Support for lazy-loading of isolated region was added in version 2. + kLazyLoading = 2, + + /// Use-list ordering started to be encoded in version 3. + kUseListOrdering = 3, + + /// Avoid recording unknown locations on block arguments (compression) started + /// in version 4. + kElideUnknownBlockArgLocation = 4, + + /// Support for encoding properties natively in bytecode instead of merged + /// with the discardable attributes. + kNativePropertiesEncoding = 5, + /// The current bytecode version. kVersion = 5, diff --git a/mlir/lib/Bytecode/Reader/BytecodeReader.cpp b/mlir/lib/Bytecode/Reader/BytecodeReader.cpp --- a/mlir/lib/Bytecode/Reader/BytecodeReader.cpp +++ b/mlir/lib/Bytecode/Reader/BytecodeReader.cpp @@ -80,7 +80,7 @@ case bytecode::Section::kDialectVersions: return true; case bytecode::Section::kProperties: - return version < 5; + return version < bytecode::kNativePropertiesEncoding; default: llvm_unreachable("unknown section ID"); } @@ -492,7 +492,7 @@ StringRef name; /// Whether this operation was registered when the bytecode was produced. - /// This flag is populated when bytecode version >=5. + /// This flag is populated when bytecode version >=kNativePropertiesEncoding. std::optional wasRegistered; }; } // namespace @@ -1647,7 +1647,7 @@ currentVersion); } // Override any request to lazy-load if the bytecode version is too old. - if (version < 2) + if (version < bytecode::kLazyLoading) lazyLoading = false; return success(); } @@ -1699,9 +1699,9 @@ // Parse each of the dialects. for (uint64_t i = 0; i < numDialects; ++i) { - /// Before version 1, there wasn't any versioning available for dialects, - /// and the entryIdx represent the string itself. - if (version == 0) { + /// Before version kDialectVersioning, there wasn't any versioning available + /// for dialects, and the entryIdx represent the string itself. + if (version < bytecode::kDialectVersioning) { if (failed(stringReader.parseString(sectionReader, dialects[i].name))) return failure(); continue; @@ -1731,9 +1731,9 @@ auto parseOpName = [&](BytecodeDialect *dialect) { StringRef opName; std::optional wasRegistered; - // Prior to version 5, the information about wheter an op was registered or - // not wasn't encoded. - if (version < 5) { + // Prior to version kNativePropertiesEncoding, the information about wheter + // an op was registered or not wasn't encoded. + if (version < bytecode::kNativePropertiesEncoding) { if (failed(stringReader.parseString(sectionReader, opName))) return failure(); } else { @@ -1746,9 +1746,9 @@ opNames.emplace_back(dialect, opName, wasRegistered); return success(); }; - // Avoid re-allocation in bytecode version > 3 where the number of ops are - // known. - if (version > 3) { + // Avoid re-allocation in bytecode version >=kElideUnknownBlockArgLocation + // where the number of ops are known. + if (version >= bytecode::kElideUnknownBlockArgLocation) { uint64_t numOps; if (failed(sectionReader.parseVarInt(numOps))) return failure(); @@ -2078,7 +2078,7 @@ RegionReadState childState(*op, &reader, isIsolatedFromAbove); // Isolated regions are encoded as a section in version 2 and above. - if (version >= 2 && isIsolatedFromAbove) { + if (version >= bytecode::kLazyLoading && isIsolatedFromAbove) { bytecode::Section::ID sectionID; ArrayRef sectionData; if (failed(reader.parseSection(sectionID, sectionData))) @@ -2229,7 +2229,8 @@ /// Parse the use-list orders for the results of the operation. Use-list /// orders are available since version 3 of the bytecode. std::optional resultIdxToUseListMap = std::nullopt; - if (version > 2 && (opMask & bytecode::OpEncodingMask::kHasUseListOrders)) { + if (version >= bytecode::kUseListOrdering && + (opMask & bytecode::OpEncodingMask::kHasUseListOrders)) { size_t numResults = opState.types.size(); auto parseResult = parseUseListOrderForRange(reader, numResults); if (failed(parseResult)) @@ -2316,7 +2317,7 @@ return failure(); // Uselist orders are available since version 3 of the bytecode. - if (version < 3) + if (version < bytecode::kUseListOrdering) return success(); uint8_t hasUseListOrders = 0; @@ -2357,7 +2358,7 @@ while (numArgs--) { Type argType; LocationAttr argLoc = unknownLoc; - if (version > 3) { + if (version >= bytecode::kElideUnknownBlockArgLocation) { // Parse the type with hasLoc flag to determine if it has type. uint64_t typeIdx; bool hasLoc; diff --git a/mlir/lib/Bytecode/Writer/BytecodeWriter.cpp b/mlir/lib/Bytecode/Writer/BytecodeWriter.cpp --- a/mlir/lib/Bytecode/Writer/BytecodeWriter.cpp +++ b/mlir/lib/Bytecode/Writer/BytecodeWriter.cpp @@ -652,7 +652,7 @@ writeStringSection(emitter); // Emit the properties section. - if (config.bytecodeVersion >= 5) + if (config.bytecodeVersion >= bytecode::kNativePropertiesEncoding) writePropertiesSection(emitter); else if (!propertiesSection.empty()) return rootOp->emitError( @@ -703,7 +703,7 @@ // Write the string section and get the ID. size_t nameID = stringSection.insert(dialect.name); - if (config.bytecodeVersion == 0) { + if (config.bytecodeVersion < bytecode::kDialectVersioning) { dialectEmitter.emitVarInt(nameID); continue; } @@ -727,13 +727,13 @@ std::move(versionEmitter)); } - if (config.bytecodeVersion > 3) + if (config.bytecodeVersion >= bytecode::kElideUnknownBlockArgLocation) dialectEmitter.emitVarInt(size(numberingState.getOpNames())); // Emit the referenced operation names grouped by dialect. auto emitOpName = [&](OpNameNumbering &name) { size_t stringId = stringSection.insert(name.name.stripDialect()); - if (config.bytecodeVersion < 5) + if (config.bytecodeVersion < bytecode::kNativePropertiesEncoding) dialectEmitter.emitVarInt(stringId); else dialectEmitter.emitVarIntWithFlag(stringId, name.name.isRegistered()); @@ -821,7 +821,7 @@ emitter.emitVarInt(args.size()); for (BlockArgument arg : args) { Location argLoc = arg.getLoc(); - if (config.bytecodeVersion > 3) { + if (config.bytecodeVersion >= bytecode::kElideUnknownBlockArgLocation) { emitter.emitVarIntWithFlag(numberingState.getNumber(arg.getType()), !isa(argLoc)); if (!isa(argLoc)) @@ -831,7 +831,7 @@ emitter.emitVarInt(numberingState.getNumber(argLoc)); } } - if (config.bytecodeVersion > 2) { + if (config.bytecodeVersion >= bytecode::kUseListOrdering) { uint64_t maskOffset = emitter.size(); uint8_t encodingMask = 0; emitter.emitByte(0); @@ -863,9 +863,10 @@ // Emit the attributes of this operation. DictionaryAttr attrs = op->getDiscardableAttrDictionary(); - // Allow deployment to version <5 by merging inherent attribute with the - // discardable ones. We should fail if there are any conflicts. - if (config.bytecodeVersion < 5) + // Allow deployment to version getAttrDictionary(); if (!attrs.empty()) { opEncodingMask |= bytecode::OpEncodingMask::kHasAttrs; @@ -873,8 +874,8 @@ } // Emit the properties of this operation, for now we still support deployment - // to version <5. - if (config.bytecodeVersion >= 5) { + // to version = bytecode::kNativePropertiesEncoding) { std::optional propertiesId = propertiesSection.emit(op); if (propertiesId.has_value()) { opEncodingMask |= bytecode::OpEncodingMask::kHasProperties; @@ -908,7 +909,7 @@ // Emit the use-list orders to bytecode, so we can reconstruct the same order // at parsing. - if (config.bytecodeVersion > 2) + if (config.bytecodeVersion >= bytecode::kUseListOrdering) writeUseListOrders(emitter, opEncodingMask, ValueRange(op->getResults())); // Check for regions. @@ -929,8 +930,9 @@ for (Region ®ion : op->getRegions()) { // If the region is not isolated from above, or we are emitting bytecode - // targeting version <2, we don't use a section. - if (!isIsolatedFromAbove || config.bytecodeVersion < 2) { + // targeting version