[llvm-branch-commits] [mlir] fc41777 - [mlir][spirv] De-template serialization
Lei Zhang via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Dec 23 12:03:54 PST 2020
Author: Lei Zhang
Date: 2020-12-23T14:54:26-05:00
New Revision: fc41777702aae1cb88512a6aa45382736766fadf
URL: https://github.com/llvm/llvm-project/commit/fc41777702aae1cb88512a6aa45382736766fadf
DIFF: https://github.com/llvm/llvm-project/commit/fc41777702aae1cb88512a6aa45382736766fadf.diff
LOG: [mlir][spirv] De-template serialization
Previously for each op we generate a separate serialization
method for it. Those serialization methods duplicate the logic
of parsing operands/results/attributes and such.
This commit creates a generic method and let suitable op-specific
serialization method to call into it.
wc -l SPIRVSerialization.inc: before 8304; after: 5597 (So -2707)
Reviewed By: hanchung, ThomasRaoux
Differential Revision: https://reviews.llvm.org/D93535
Added:
Modified:
mlir/lib/Target/SPIRV/Serialization.cpp
mlir/tools/mlir-tblgen/SPIRVUtilsGen.cpp
Removed:
################################################################################
diff --git a/mlir/lib/Target/SPIRV/Serialization.cpp b/mlir/lib/Target/SPIRV/Serialization.cpp
index db00f5ecf899..c530cccd4232 100644
--- a/mlir/lib/Target/SPIRV/Serialization.cpp
+++ b/mlir/lib/Target/SPIRV/Serialization.cpp
@@ -364,15 +364,23 @@ class Serializer {
/// Main dispatch method for serializing an operation.
LogicalResult processOperation(Operation *op);
- /// Method to dispatch to the serialization function for an operation in
- /// SPIR-V dialect that is a mirror of an instruction in the SPIR-V spec.
- /// This is auto-generated from ODS. Dispatch is handled for all operations
- /// in SPIR-V dialect that have hasOpcode == 1.
+ /// Serializes an operation `op` as core instruction with `opcode` if
+ /// `extInstSet` is empty. Otherwise serializes it as an extended instruction
+ /// with `opcode` from `extInstSet`.
+ /// This method is a generic one for dispatching any SPIR-V ops that has no
+ /// variadic operands and attributes in TableGen definitions.
+ LogicalResult processOpWithoutGrammarAttr(Operation *op, StringRef extInstSet,
+ uint32_t opcode);
+
+ /// Dispatches to the serialization function for an operation in SPIR-V
+ /// dialect that is a mirror of an instruction in the SPIR-V spec. This is
+ /// auto-generated from ODS. Dispatch is handled for all operations in SPIR-V
+ /// dialect that have hasOpcode == 1.
LogicalResult dispatchToAutogenSerialization(Operation *op);
- /// Method to serialize an operation in the SPIR-V dialect that is a mirror of
- /// an instruction in the SPIR-V spec. This is auto generated if hasOpcode ==
- /// 1 and autogenSerialization == 1 in ODS.
+ /// Serializes an operation in the SPIR-V dialect that is a mirror of an
+ /// instruction in the SPIR-V spec. This is auto generated if hasOpcode == 1
+ /// and autogenSerialization == 1 in ODS.
template <typename OpTy>
LogicalResult processOp(OpTy op) {
return op.emitError("unsupported op serialization");
@@ -1930,6 +1938,46 @@ LogicalResult Serializer::processOperation(Operation *opInst) {
[&](Operation *op) { return dispatchToAutogenSerialization(op); });
}
+LogicalResult Serializer::processOpWithoutGrammarAttr(Operation *op,
+ StringRef extInstSet,
+ uint32_t opcode) {
+ SmallVector<uint32_t, 4> operands;
+ Location loc = op->getLoc();
+
+ uint32_t resultID = 0;
+ if (op->getNumResults() != 0) {
+ uint32_t resultTypeID = 0;
+ if (failed(processType(loc, op->getResult(0).getType(), resultTypeID)))
+ return failure();
+ operands.push_back(resultTypeID);
+
+ resultID = getNextID();
+ operands.push_back(resultID);
+ valueIDMap[op->getResult(0)] = resultID;
+ };
+
+ for (Value operand : op->getOperands())
+ operands.push_back(getValueID(operand));
+
+ emitDebugLine(functionBody, loc);
+
+ if (extInstSet.empty()) {
+ encodeInstructionInto(functionBody, static_cast<spirv::Opcode>(opcode),
+ operands);
+ } else {
+ encodeExtensionInstruction(op, extInstSet, opcode, operands);
+ }
+
+ if (op->getNumResults() != 0) {
+ for (auto attr : op->getAttrs()) {
+ if (failed(processDecoration(loc, resultID, attr)))
+ return failure();
+ }
+ }
+
+ return success();
+}
+
namespace {
template <>
LogicalResult
diff --git a/mlir/tools/mlir-tblgen/SPIRVUtilsGen.cpp b/mlir/tools/mlir-tblgen/SPIRVUtilsGen.cpp
index ab520114e7f5..74fe1e0fdb08 100644
--- a/mlir/tools/mlir-tblgen/SPIRVUtilsGen.cpp
+++ b/mlir/tools/mlir-tblgen/SPIRVUtilsGen.cpp
@@ -647,8 +647,7 @@ static void emitDecorationSerialization(const Operator &op, StringRef tabs,
// All non-argument attributes translated into OpDecorate instruction
os << tabs << formatv("for (auto attr : {0}->getAttrs()) {{\n", opVar);
os << tabs
- << formatv(" if (llvm::any_of({0}, [&](StringRef elided)", elidedAttrs);
- os << " {return attr.first == elided;})) {\n";
+ << formatv(" if (llvm::is_contained({0}, attr.first)) {{", elidedAttrs);
os << tabs << " continue;\n";
os << tabs << " }\n";
os << tabs
@@ -666,14 +665,35 @@ static void emitSerializationFunction(const Record *attrClass,
const Record *record, const Operator &op,
raw_ostream &os) {
// If the record has 'autogenSerialization' set to 0, nothing to do
- if (!record->getValueAsBit("autogenSerialization")) {
+ if (!record->getValueAsBit("autogenSerialization"))
return;
- }
+
StringRef opVar("op"), operands("operands"), elidedAttrs("elidedAttrs"),
resultID("resultID");
+
os << formatv(
"template <> LogicalResult\nSerializer::processOp<{0}>({0} {1}) {{\n",
op.getQualCppClassName(), opVar);
+
+ // Special case for ops without attributes in TableGen definitions
+ if (op.getNumAttributes() == 0 && op.getNumVariableLengthOperands() == 0) {
+ std::string extInstSet;
+ std::string opcode;
+ if (record->isSubClassOf("SPV_ExtInstOp")) {
+ extInstSet =
+ formatv("\"{0}\"", record->getValueAsString("extendedInstSetName"));
+ opcode = std::to_string(record->getValueAsInt("extendedInstOpcode"));
+ } else {
+ extInstSet = "\"\"";
+ opcode = formatv("static_cast<uint32_t>(spirv::Opcode::{0})",
+ record->getValueAsString("spirvOpName"));
+ }
+
+ os << formatv(" return processOpWithoutGrammarAttr({0}, {1}, {2});\n}\n\n",
+ opVar, extInstSet, opcode);
+ return;
+ }
+
os << formatv(" SmallVector<uint32_t, 4> {0};\n", operands);
os << formatv(" SmallVector<StringRef, 2> {0};\n", elidedAttrs);
More information about the llvm-branch-commits
mailing list