================
@@ -0,0 +1,344 @@
+//===-- CIRDialectBytecode.td - CIR bytecode 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 CIR bytecode reader/writer definition file.
+//
+// Modelled on mlir/include/mlir/Dialect/LLVMIR/LLVMDialectBytecode.td. Every
+// entry's parameters must appear in the same order as the attribute's get(),
+// because the generated reader feeds them positionally, and each name must
+// derive the C++ getter (`get` + the name in UpperCamel).
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef CIR_DIALECT_BYTECODE
+#define CIR_DIALECT_BYTECODE
+
+include "mlir/IR/BytecodeBase.td"
+
+//===----------------------------------------------------------------------===//
+// Bytecode classes for attributes and types.
+//===----------------------------------------------------------------------===//
+
+class Attr<string type> : WithType<type, Attribute>;
+
+// Read a generic type into a narrowed C++ handle. The reader's templated
+// readType does the dyn_cast and fails cleanly on a mismatch, so this stays
+// safe against a malformed or cross-version file.
+class Ty<string type> : WithType<type, Type>;
+
+class OptionalAttribute<string type> :
+  WithParser <"succeeded($_reader.readOptionalAttribute($_var))",
+  WithPrinter<"$_writer.writeOptionalAttribute($_getter)",
+  WithType<type, Attribute>>>;
+
+// For a parameter declared OptionalParameter<"std::optional<...>">, where the
+// C++ type is an optional rather than a nullable attribute, so "absent" needs
+// a flag of its own. The helpers live in CIRDialectBytecode.cpp.
+class OptionalInt<string type> :
+  WithParser <"succeeded(readOptionalInt($_reader, $_var))",
+  WithBuilder<"$_args",
+  WithPrinter<"writeOptionalInt($_writer, $_getter)",
+  WithType   <"std::optional<" # type # ">">>>>;
+
+// Named for the C++ spelling, not the concept, because the difference from
+// OptionalAttribute above is exactly the C++ spelling and nothing else:
+// OptionalAttribute is for a parameter that is a nullable attribute, this is
+// for one declared std::optional<...>. The two share the same wire format, so
+// at a glance nothing but the name says which a given parameter needs.
+class StdOptionalAttribute<string type> :
+  WithParser <"succeeded(readStdOptionalAttribute($_reader, $_var))",
+  WithBuilder<"$_args",
+  WithPrinter<"writeStdOptionalAttribute($_writer, $_getter)",
+  WithType   <"std::optional<" # type # ">">>>>;
+
+// A scoped enum read from an untrusted varint. The value is validated with
+// the enum's symbolizer; an out-of-range value fails the read with a
+// diagnostic instead of casting into undefined behavior.
+def CtorKindParam :
+  WithParser<"succeeded(readEnum($_reader, $_var, cir::symbolizeCtorKind, 
\"CtorKind\"))",
+  WithPrinter<"$_writer.writeVarInt(static_cast<uint64_t>($_getter))",
+  WithType<"cir::CtorKind">>>;
+
+def AssignKindParam :
+  WithParser<"succeeded(readEnum($_reader, $_var, cir::symbolizeAssignKind, 
\"AssignKind\"))",
+  WithPrinter<"$_writer.writeVarInt(static_cast<uint64_t>($_getter))",
+  WithType<"cir::AssignKind">>>;
+
+// A varint on the wire narrowed to a fixed-width integer. The bound is checked
+// on read; a file carrying a value the parameter cannot hold fails instead of
+// truncating into a plausible count or index.
+def CheckedInt :
+  WithParser<"succeeded(readCheckedInt($_reader, $_var))",
+  WithPrinter<"$_writer.writeSignedVarInt($_getter)",
+  WithType<"int">>>;
+
+def CheckedInt32 :
+  WithParser<"succeeded(readCheckedInt($_reader, $_var))",
+  WithPrinter<"$_writer.writeSignedVarInt($_getter)",
+  WithType<"int32_t">>>;
+
+def CheckedUnsigned :
+  WithParser<"succeeded(readCheckedInt($_reader, $_var))",
+  WithPrinter<"$_writer.writeVarInt($_getter)",
+  WithType<"unsigned">>>;
+
+//===----------------------------------------------------------------------===//
+// OptInfoAttr
+//===----------------------------------------------------------------------===//
+
+def OptInfoAttr : DialectAttribute<(attr
+  CheckedUnsigned:$level,
+  CheckedUnsigned:$size
+)>;
+
+//===----------------------------------------------------------------------===//
+// AddressPointAttr
+//
+// index and offset are int32_t and an address point legitimately carries a
+// negative offset, so these are signed.
+//===----------------------------------------------------------------------===//
+
+def AddressPointAttr : DialectAttribute<(attr
+  CheckedInt32:$index,
+  CheckedInt32:$offset
+)>;
+
+//===----------------------------------------------------------------------===//
+// OpenCLVersionAttr
+//===----------------------------------------------------------------------===//
+
+def OpenCLVersionAttr : DialectAttribute<(attr
+  CheckedInt32:$major,
+  CheckedInt32:$minor
+)>;
+
+//===----------------------------------------------------------------------===//
+// BlockAddrInfoAttr
+//===----------------------------------------------------------------------===//
+
+def BlockAddrInfoAttr : DialectAttribute<(attr
+  Ty<"cir::PointerType">:$type,
+  Attr<"mlir::FlatSymbolRefAttr">:$func,
+  Attr<"mlir::StringAttr">:$label
+)>;
+
+//===----------------------------------------------------------------------===//
+// BitfieldInfoAttr
+//===----------------------------------------------------------------------===//
+
+def BitfieldInfoAttr : DialectAttribute<(attr
+  Attr<"mlir::StringAttr">:$name,
+  Type:$storage_type,
+  VarInt:$size,
+  VarInt:$offset,
+  Bool:$is_signed
+)>;
+
+//===----------------------------------------------------------------------===//
+// Constants
+//===----------------------------------------------------------------------===//
+//
+// These are the entries that pay for themselves. Every literal in a function
+// body is an IntAttr, an FPAttr or a BoolAttr, so under the assembly fallback
+// each one costs its full printed form ("#cir.int<42> : !s32i") while the
+// native encoding costs a type reference plus the payload's own width.
+
+// The value's width is implied by the type, so it is not stored twice; the
+// helpers below recover it. This mirrors builtin's IntegerAttr / FloatAttr.
+def IntAttr : DialectAttribute<(attr
+  Type:$type,
+  KnownWidthAPInt<"type">:$value
+)> {
+  let cBuilder = "get<$_resultType>(context, 
mlir::cast<cir::IntTypeInterface>(type), *value)";
+}
+
+def FPAttr : DialectAttribute<(attr
+  Type:$type,
+  KnownSemanticsAPFloat<"type">:$value
+)> {
+  let cBuilder = "get<$_resultType>(context, 
mlir::cast<cir::FPTypeInterface>(type), *value)";
+}
+
+// cir::BoolType is a singleton, so the self type carries no information and is
+// rebuilt on read rather than stored.
+def BoolAttr : DialectAttribute<(attr
+  Bool:$value
+)> {
+  let cBuilder = "get<$_resultType>(context, cir::BoolType::get(context), 
value)";
+}
+
+def ConstPtrAttr : DialectAttribute<(attr
+  Ty<"cir::PointerType">:$type,
+  Attr<"mlir::IntegerAttr">:$value
+)>;
+
+//===----------------------------------------------------------------------===//
+// Parameterless marker attributes
+//===----------------------------------------------------------------------===//
+//
+// No payload at all: the entry exists so the attribute costs a kind index
+// instead of its printed mnemonic.
+
+def CatchAllAttr : DialectAttribute<(attr)>;
+def UnwindAttr : DialectAttribute<(attr)>;
+
+//===----------------------------------------------------------------------===//
+// Constant initializers
+//===----------------------------------------------------------------------===//
+//
+// These carry a self type, and under the fallback each *occurrence* embeds
+// that type's whole printed form, so a zero-initialized aggregate costs the
+// full type text at every use. Encoding them natively writes a reference
+// into the bytecode type table instead.
+
+def ZeroAttr : DialectAttribute<(attr
+  Type:$type
+)>;
+
+def UndefAttr : DialectAttribute<(attr
+  Type:$type
+)>;
+
+def PoisonAttr : DialectAttribute<(attr
+  Type:$type
+)>;
+
+def ConstArrayAttr : DialectAttribute<(attr
+  Type:$type,
+  Attribute:$elts,
+  CheckedInt:$trailingZerosNum
+)> {
+  let cBuilder = "getChecked<$_resultType>([&]() { return reader.emitError(); 
}, context, type, elts, trailingZerosNum)";
----------------
xlauko wrote:

this can be dropped `DialectAttribute` already defaults to the same `cBuilder`.

https://github.com/llvm/llvm-project/pull/229586
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to