//===-- BytecodeBase.td - Base bytecode R/W defs -----------*- tablegen -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This is the base bytecode reader/writer definition file. // //===----------------------------------------------------------------------===// #ifndef BYTECODE_BASE #define BYTECODE_BASE class Bytecode { // Template for parsing. // $_reader == dialect bytecode reader // $_resultType == result type of parsed instance // $_var == variable being parsed // If parser is not specified, then the parse of members is used. string cParser = parse; // Template for building from parsed. // $_resultType == result type of parsed instance // $_args == args/members comma separated string cBuilder = build; // Template for printing. // $_writer == dialect bytecode writer // $_name == parent attribute/type name // $_getter == getter string cPrinter = print; // Template for getter from in memory form. // $_attrType == attribute/type // $_member == member instance // $_getMember == get + UpperCamelFromSnake($_member) string cGetter = get; // Type built. // Note: if cType is empty, then name of def is used. string cType = t; // Predicate guarding parse method as an Attribute/Type could have multiple // parse methods, specify predicates to be orthogonal and cover entire // "print space" to avoid order dependence. // If empty then method is unconditional. // $_val == predicate function to apply on value dyn_casted to cType. string printerPredicate = ""; } class WithParser> : Bytecode; class WithBuilder> : Bytecode; class WithPrinter> : Bytecode; class WithType> : Bytecode; class WithGetter> : Bytecode; // Representation of a bytecode element consisting of other bytecode atoms. // E.g., it is effectively a struct of bytecode elements. Set the members by // define a members dag: `dag members = (attr ...)`. class CompositeBytecode : WithType; class AttributeKind : WithParser <"succeeded($_reader.readAttribute($_var))", WithBuilder<"$_args", WithPrinter<"$_writer.writeAttribute($_getter)">>>; def Attribute : AttributeKind; class TypeKind : WithParser <"succeeded($_reader.readType($_var))", WithBuilder<"$_args", WithPrinter<"$_writer.writeType($_getter)">>>; def Type : TypeKind; def VarInt : WithParser <"succeeded($_reader.readVarInt($_var))", WithBuilder<"$_args", WithPrinter<"$_writer.writeVarInt($_getter)", WithType <"uint64_t">>>>; def SignedVarInt : WithParser <"succeeded($_reader.readSignedVarInt($_var))", WithBuilder<"$_args", WithPrinter<"$_writer.writeSignedVarInt($_getter)", WithType <"int64_t">>>>; def Blob : WithParser <"succeeded($_reader.readBlob($_var))", WithBuilder<"$_args", WithPrinter<"$_writer.writeOwnedBlob($_getter)", WithType <"ArrayRef">>>>; def Bool : WithParser <"succeeded($_reader.readBool($_var))", WithBuilder<"$_args", WithPrinter<"$_writer.writeOwnedBool($_getter)", WithType <"bool">>>>; class KnownWidthAPInt : WithParser <"succeeded(readAPIntWithKnownWidth($_reader, " # s # ", $_var))", WithBuilder<"$_args", WithPrinter<"$_writer.writeAPIntWithKnownWidth($_getter)", WithType <"FailureOr">>>>; class KnownSemanticsAPFloat : WithParser <"succeeded(readAPFloatWithKnownSemantics($_reader, " # s # ", $_var))", WithBuilder<"$_args", WithPrinter<"$_writer.writeAPFloatWithKnownSemantics($_getter)", WithType <"FailureOr">>>>; class ResourceHandle : WithParser <"succeeded(readResourceHandle<" # s # ">($_reader, $_var))", WithBuilder<"$_args", WithPrinter<"$_writer.writeResourceHandle($_getter)", WithType <"FailureOr<" # s # ">">>>>; // Helper to define variable that is defined later but not parsed nor printed. class LocalVar : WithParser <"(($_var = " # d # "), true)", WithBuilder<"$_args", WithPrinter<"", WithType >>>; // Array instances. class Array { Bytecode elemT = t; string cBuilder = "$_args"; } // - Array elements currently needs a different bytecode type to accommodate // for the list print/parsing. class List : WithGetter<"$_member", t>; def SignedVarIntList : List; def BoolList : List; // Define dialect attribute or type. class DialectAttrOrType { // Any members starting with underscore is not fed to create function but // treated as purely local variable. dag members = d; // When needing to specify a custom return type. string cType = ""; // Any post-processing that needs to be done. code postProcess = ""; } class DialectAttribute : DialectAttrOrType, AttributeKind { let cParser = "succeeded($_reader.readAttribute<$_resultType>($_var))"; let cBuilder = "getChecked<$_resultType>([&]() { return reader.emitError(); }, context, $_args)"; } class DialectType : DialectAttrOrType, TypeKind { let cParser = "succeeded($_reader.readType<$_resultType>($_var))"; let cBuilder = "getChecked<$_resultType>([&]() { return reader.emitError(); }, context, $_args)"; } // Variant of the above, where it never prints. Useful for staging. class DialectTypeNoPrint : DialectType { let printerPredicate = "false"; } class DialectAttributes { string dialect = d; list elems; } class DialectTypes { string dialect = d; list elems; } def attr; def type; // Marker to indicate a skipped attribute or type in the enum. Could either be // reserved for a future value or for marking a previously used value as dead. def none; def ReservedOrDead : DialectAttrOrType<(none)>; #endif // BYTECODE_BASE