| 947 | |
| 948 | namespace { |
| 949 | struct FunctionTableWriter { |
| 950 | FunctionTableWriter(TypeManager &tm, ConstantManager &cm, StringManager &sm, |
| 951 | DebugInfoWriter &dm, const BytecodeWriterConfig &cfg) |
| 952 | : typeMgr(tm), constMgr(cm), strMgr(sm), debuginfo(dm), config(cfg) {} |
| 953 | |
| 954 | LogicalResult writeOperation(Operation *op, EncodingWriter &writer) { |
| 955 | auto opcode = getOpcodeForOperation(op); |
| 956 | if (!opcode) |
| 957 | return op->emitError("operation not supported in bytecode (missing from " |
| 958 | "BytecodeOpcodes.td)"); |
| 959 | |
| 960 | // Version checking for public operations. |
| 961 | uint32_t opcodeValue = static_cast<uint32_t>(*opcode); |
| 962 | if (!mlir::cuda_tile::detail::isOpcodeAvailableInVersion( |
| 963 | opcodeValue, config.bytecodeVersion)) |
| 964 | return op->emitError() << "operation '" << op->getName().getStringRef() |
| 965 | << "' is not available in bytecode version " |
| 966 | << config.bytecodeVersion.toString(); |
| 967 | |
| 968 | writer.writeVarInt(*opcode); |
| 969 | |
| 970 | if (failed(debuginfo.validateDebugInfo(op))) |
| 971 | return failure(); |
| 972 | |
| 973 | uint64_t functionLocIndex = |
| 974 | debuginfo.getOpIndex(op->getParentOfType<FunctionOpInterface>()); |
| 975 | debuginfo.addDebugInfo(functionLocIndex, op->getLoc()); |
| 976 | |
| 977 | auto numSerializedResults = |
| 978 | dispatchOpWriter(op, writer, typeMgr, constMgr, strMgr, config); |
| 979 | if (failed(numSerializedResults)) |
| 980 | return failure(); |
| 981 | // Only add serialized results to valueIndexMap. Results that were not |
| 982 | // serialized (due to version compatibility) should not be indexed. |
| 983 | for (size_t i = 0; i < *numSerializedResults; ++i) |
| 984 | valueIndexMap[op->getResult(i)] = nextValueIndex++; |
| 985 | return success(); |
| 986 | } |
| 987 | |
| 988 | std::optional<Bytecode::Opcode> getOpcodeForOperation(Operation *op) { |
| 989 | auto it = Bytecode::getOpcodeMap().find(op->getName().getStringRef()); |
| 990 | if (it != Bytecode::getOpcodeMap().end()) |
| 991 | return it->second; |
| 992 | return std::nullopt; |
| 993 | } |
| 994 | |
| 995 | // Writes the operands of an operation to the bytecode |
| 996 | void writeOperands(ValueRange operands, EncodingWriter &writer, |
| 997 | bool encodeSize = true) { |
| 998 | if (encodeSize) |
| 999 | writer.writeVarInt(operands.size()); |
| 1000 | for (Value operand : operands) { |
| 1001 | uint64_t operandIndex = valueIndexMap.lookup(operand); |
| 1002 | writer.writeVarInt(operandIndex); |
| 1003 | } |
| 1004 | } |
| 1005 | |
| 1006 | // Writes result types from a TypeRange to the bytecode. |
nothing calls this directly
no outgoing calls
no test coverage detected