[llvm] [Offload] Introduce `offload-tblgen` (PR #88923)

via llvm-commits llvm-commits at lists.llvm.org
Thu Apr 18 04:43:09 PDT 2024


llvmbot wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-offload

Author: Callum Fare (callumfare)

<details>
<summary>Changes</summary>

Introduce `offload-tblgen`, which will be used for automatically generating some source files for the Offload project. The tablegen files are intended to be the 'single source of truth' for the new API, with the header file automatically generated, along with other useful source and .inc files.

This is an initial implementation intended to be a useful starting off point for discussion, and is based on tooling from Unified Runtime as previously discussed. I'm expecting a lot of iteration and discussion before anything is merged, so all feedback is welcome.

See `offload/API/README.md` for more documentation.

Notable things still to be done (not necessarily before this PR is merged):
* Decide on exactly what features are desirable. A lot of this is lifted from the equivalent templates and scripts in Unified Runtime, and obviously not everything will be relevant.
* Decide on a prefix to use for API naming (like `cu` for cuda or `cl` for OpenCL). Currently set to `ol` for the sake of brevity. Could also be `offl`, `offload` or something else. This is plumbed into quite a few places so makes sense to decide early.
* Check that the doxygen comments in the generated header can actually be used to generate documentation
* Implement tracing/printing backend
* Finish the validation backend
* Implement some kind of test generation

---

Patch is 57.88 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/88923.diff


14 Files Affected:

- (modified) llvm/CMakeLists.txt (+2-2) 
- (modified) llvm/projects/CMakeLists.txt (+1) 
- (added) offload/API/APIDefs.td (+183) 
- (added) offload/API/Example.td (+490) 
- (added) offload/API/OffloadAPI.td (+13) 
- (added) offload/API/README.md (+103) 
- (added) offload/CMakeLists.txt (+19) 
- (added) offload/tools/offload-tblgen/APIGen.cpp (+169) 
- (added) offload/tools/offload-tblgen/CMakeLists.txt (+20) 
- (added) offload/tools/offload-tblgen/GenCommon.hpp (+28) 
- (added) offload/tools/offload-tblgen/Generators.hpp (+14) 
- (added) offload/tools/offload-tblgen/RecordTypes.hpp (+194) 
- (added) offload/tools/offload-tblgen/ValidationGen.cpp (+134) 
- (added) offload/tools/offload-tblgen/offload-tblgen.cpp (+74) 


``````````diff
diff --git a/llvm/CMakeLists.txt b/llvm/CMakeLists.txt
index d511376e18ba5e..d1c0469aa0e31a 100644
--- a/llvm/CMakeLists.txt
+++ b/llvm/CMakeLists.txt
@@ -114,7 +114,7 @@ endif()
 # LLVM_EXTERNAL_${project}_SOURCE_DIR using LLVM_ALL_PROJECTS
 # This allows an easy way of setting up a build directory for llvm and another
 # one for llvm+clang+... using the same sources.
-set(LLVM_ALL_PROJECTS "bolt;clang;clang-tools-extra;compiler-rt;cross-project-tests;libc;libclc;lld;lldb;mlir;openmp;polly;pstl")
+set(LLVM_ALL_PROJECTS "bolt;clang;clang-tools-extra;compiler-rt;cross-project-tests;libc;libclc;lld;lldb;mlir;openmp;polly;pstl;offload")
 # The flang project is not yet part of "all" projects (see C++ requirements)
 set(LLVM_EXTRA_PROJECTS "flang")
 # List of all known projects in the mono repo
@@ -147,7 +147,7 @@ endif()
 # As we migrate runtimes to using the bootstrapping build, the set of default runtimes
 # should grow as we remove those runtimes from LLVM_ENABLE_PROJECTS above.
 set(LLVM_DEFAULT_RUNTIMES "libcxx;libcxxabi;libunwind")
-set(LLVM_SUPPORTED_RUNTIMES "libc;libunwind;libcxxabi;pstl;libcxx;compiler-rt;openmp;llvm-libgcc")
+set(LLVM_SUPPORTED_RUNTIMES "libc;libunwind;libcxxabi;pstl;libcxx;compiler-rt;openmp;llvm-libgcc;offload")
 set(LLVM_ENABLE_RUNTIMES "" CACHE STRING
   "Semicolon-separated list of runtimes to build, or \"all\" (${LLVM_DEFAULT_RUNTIMES}). Supported runtimes are ${LLVM_SUPPORTED_RUNTIMES}.")
 if(LLVM_ENABLE_RUNTIMES STREQUAL "all")
diff --git a/llvm/projects/CMakeLists.txt b/llvm/projects/CMakeLists.txt
index 08f2fa522420b0..ae0247a5bb60d5 100644
--- a/llvm/projects/CMakeLists.txt
+++ b/llvm/projects/CMakeLists.txt
@@ -41,6 +41,7 @@ endif()
 
 add_llvm_external_project(dragonegg)
 add_llvm_external_project(openmp)
+add_llvm_external_project(offload)
 
 if(LLVM_INCLUDE_TESTS)
   add_llvm_external_project(cross-project-tests)
diff --git a/offload/API/APIDefs.td b/offload/API/APIDefs.td
new file mode 100644
index 00000000000000..d22da0282f8c32
--- /dev/null
+++ b/offload/API/APIDefs.td
@@ -0,0 +1,183 @@
+//===-- APIDefs.td - Base definitions for Offload tablegen -*- 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 file contains the class definitions used to implement the Offload API,
+// as well as helper functions used to help populate relevant records.
+// See offload/API/README.md for more detailed documentation.
+//
+//===----------------------------------------------------------------------===//
+
+
+// Parameter flags
+defvar PARAM_IN = 0x1;
+defvar PARAM_OUT = 0x2;
+defvar PARAM_OPTIONAL = 0x4;
+
+// Prefix for API naming. This could be hard-coded in the future when a value
+// is agreed upon.
+defvar PREFIX = "OL";
+defvar prefix = !tolower(PREFIX);
+
+// Does the type end with '_handle_t'?
+class IsHandleType<string Type> {
+  // size("_handle_t") == 9
+  bit ret = !if(!lt(!size(Type), 9), 0,
+                !ne(!find(Type, "_handle_t", !sub(!size(Type), 9)), -1));
+}
+
+// Does the type end with '*'?
+class IsPointerType<string Type> {
+  bit ret = !ne(!find(Type, "*", !sub(!size(Type), 1)), -1);
+}
+
+class Param<string Type, string Name, string Desc, bits<3> Flags = 0> {
+  string type = Type;
+  string name = Name;
+  string desc = Desc;
+  bits<3> flags = Flags;
+  bit IsHandle = IsHandleType<type>.ret;
+  bit IsPointer = IsPointerType<type>.ret;
+}
+
+class Return<string Value, list<string> Conditions = []> {
+  string value = Value;
+  list<string> conditions = Conditions;
+}
+
+class ShouldCheckHandle<Param P> {
+  bit ret = !and(P.IsHandle, !eq(!and(PARAM_OPTIONAL, P.flags), 0));
+}
+
+class ShouldCheckPointer<Param P> {
+  bit ret = !and(P.IsPointer, !eq(!and(PARAM_OPTIONAL, P.flags), 0));
+}
+
+// For a list of returns that contains a specific return code, find and append
+// new conditions to that return
+class AppendConditionsToReturn<list<Return> Returns, string ReturnValue,
+                               list<string> Conditions> {
+  list<Return> ret =
+      !foreach(Ret, Returns,
+               !if(!eq(Ret.value, ReturnValue),
+                   Return<Ret.value, Ret.conditions#Conditions>, Ret));
+}
+
+// Add null handle checks to a function's return value descriptions
+class AddHandleChecksToReturns<list<Param> Params, list<Return> Returns> {
+  list<string> handle_params =
+      !foreach(P, Params, !if(ShouldCheckHandle<P>.ret, P.name, ""));
+  list<string> handle_params_filt =
+      !filter(param, handle_params, !ne(param, ""));
+  list<string> handle_param_conds =
+      !foreach(handle, handle_params_filt, "`NULL == "#handle#"`");
+
+  // Does the list of returns already contain ERROR_INVALID_NULL_HANDLE?
+  bit returns_has_inv_handle = !foldl(
+      0, Returns, HasErr, Ret,
+      !or(HasErr, !eq(Ret.value, PREFIX#"_RESULT_ERROR_INVALID_NULL_HANDLE")));
+
+  list<Return> returns_out = !if(returns_has_inv_handle,
+        AppendConditionsToReturn<Returns, PREFIX # "_RESULT_ERROR_INVALID_NULL_HANDLE", handle_param_conds>.ret,
+        !listconcat(Returns, [Return<PREFIX # "_RESULT_ERROR_INVALID_NULL_HANDLE", handle_param_conds>])
+    );
+}
+
+// Add null pointer checks to a function's return value descriptions
+class AddPointerChecksToReturns<list<Param> Params, list<Return> Returns> {
+  list<string> ptr_params =
+      !foreach(P, Params, !if(ShouldCheckPointer<P>.ret, P.name, ""));
+  list<string> ptr_params_filt = !filter(param, ptr_params, !ne(param, ""));
+  list<string> ptr_param_conds =
+      !foreach(ptr, ptr_params_filt, "`NULL == "#ptr#"`");
+
+  // Does the list of returns already contain ERROR_INVALID_NULL_POINTER?
+  bit returns_has_inv_ptr = !foldl(
+      0, Returns, HasErr, Ret,
+      !or(HasErr, !eq(Ret.value, PREFIX#"_RESULT_ERROR_INVALID_NULL_POINTER")));
+  list<Return> returns_out = !if(returns_has_inv_ptr,
+        AppendConditionsToReturn<Returns, PREFIX # "_RESULT_ERROR_INVALID_NULL_POINTER", ptr_param_conds>.ret,
+        !listconcat(Returns, [Return<PREFIX # "_RESULT_ERROR_INVALID_NULL_POINTER", ptr_param_conds>])
+    );
+}
+
+defvar DefaultReturns = [Return<PREFIX#"_RESULT_SUCCESS">,
+                         Return<PREFIX#"_RESULT_ERROR_UNINITIALIZED">,
+                         Return<PREFIX#"_RESULT_ERROR_DEVICE_LOST">,
+                         Return<PREFIX#"_RESULT_ERROR_ADAPTER_SPECIFIC">];
+
+class APIObject {
+  string name;
+  string desc;
+}
+
+class Function<string Class> : APIObject {
+  string api_class = Class;
+  list<Param> params;
+  list<Return> returns;
+  list<string> details = [];
+  list<string> analogues = [];
+
+  list<Return> returns_with_def = !listconcat(DefaultReturns, returns);
+  list<Return> all_returns = AddPointerChecksToReturns<params,
+        AddHandleChecksToReturns<params, returns_with_def>.returns_out>.returns_out;
+}
+
+class Etor<string Name, string Desc> {
+  string name = Name;
+  string desc = Desc;
+}
+
+class Enum : APIObject {
+  // This refers to whether the enumerator descriptions specify a return
+  // type for functions where this enum may be used as an input type.
+  // The format is "[$x_some_return_t] Description text"
+  // (TODO: This is lifted from UR, is it relevant?)
+  bit is_typed = 0;
+
+  list<Etor> etors = [];
+}
+
+class StructMember<string Type, string Name, string Desc> {
+  string type = Type;
+  string name = Name;
+  string desc = Desc;
+}
+
+defvar DefaultPropStructMembers =
+    [StructMember<prefix#"_structure_type_t", "stype",
+                  "type of this structure">,
+     StructMember<"void*", "pNext", "pointer to extension-specific structure">];
+
+class StructHasInheritedMembers<string BaseClass> {
+  bit ret = !or(!eq(BaseClass, prefix#"_base_properties_t"),
+                !eq(BaseClass, prefix#"_base_desc_t"));
+}
+
+class Struct : APIObject {
+  string base_class = "";
+  list<StructMember> members;
+  list<StructMember> all_members =
+      !if(StructHasInheritedMembers<base_class>.ret,
+          DefaultPropStructMembers, [])#members;
+}
+
+class Typedef : APIObject { string value; }
+
+class FptrTypedef : APIObject {
+  list<Param> params;
+  list<Return> returns;
+}
+
+class Macro : APIObject {
+  string value;
+
+  string condition;
+  string alt_value;
+}
+
+class Handle : APIObject;
diff --git a/offload/API/Example.td b/offload/API/Example.td
new file mode 100644
index 00000000000000..b78ce635066054
--- /dev/null
+++ b/offload/API/Example.td
@@ -0,0 +1,490 @@
+//===-- Example.td - Example definitions for Offload -------*- 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 file serves as an example for the Offload tablegen framework.
+// It is NOT an actual representation of the API. It is based off a random
+// selection of features from Unified Runtime.
+//
+//===----------------------------------------------------------------------===//
+
+
+def : Macro {
+  let name = "OL_MAKE_VERSION( _major, _minor )";
+  let desc = "Generates generic API versions";
+  let value = "(( _major << 16 )|( _minor & 0x0000ffff))";
+}
+
+def : Macro {
+  let name = "OL_MAJOR_VERSION( _ver )";
+  let desc = "Extracts API major version";
+  let value = "( _ver >> 16 )";
+}
+
+def : Macro {
+  let name = "OL_MINOR_VERSION( _ver )";
+  let desc = "Extracts API minor version";
+  let value = "( _ver & 0x0000ffff )";
+}
+
+def : Macro {
+  let name = "OL_APICALL";
+  let desc = "Calling convention for all API functions";
+  let condition = "defined(_WIN32)";
+  let value = "__cdecl";
+  let alt_value = "";
+}
+
+def : Macro {
+  let name = "OL_APIEXPORT";
+  let desc = "Microsoft-specific dllexport storage-class attribute";
+  let condition = "defined(_WIN32)";
+  let value = "__declspec(dllexport)";
+  let alt_value = "";
+}
+
+def : Macro {
+  let name = "OL_DLLEXPORT";
+  let desc = "Microsoft-specific dllexport storage-class attribute";
+  let condition = "defined(_WIN32)";
+  let value = "__declspec(dllexport)";
+}
+
+def : Macro {
+  let name = "OL_DLLEXPORT";
+  let desc = "GCC-specific dllexport storage-class attribute";
+  let condition = "__GNUC__ >= 4";
+  let value = "__attribute__ ((visibility (\"default\")))";
+  let alt_value = "";
+}
+
+def : Typedef {
+  let name = "ol_bool_t";
+  let value = "uint8_t";
+  let desc = "compiler-independent type";
+}
+
+def : Handle {
+  let name = "ol_loader_config_handle_t";
+  let desc = "Handle of a loader config object";
+}
+
+def : Handle {
+  let name = "ol_adapter_handle_t";
+  let desc = "Handle of an adapter instance";
+}
+
+def : Handle {
+  let name = "ol_platform_handle_t";
+  let desc = "Handle of a platform instance";
+}
+
+def : Handle {
+  let name = "ol_device_handle_t";
+  let desc = "Handle of platform's device object";
+}
+
+def : Handle {
+  let name = "ol_context_handle_t";
+  let desc = "Handle of context object";
+}
+
+def : Handle {
+  let name = "ol_event_handle_t";
+  let desc = "Handle of event object";
+}
+
+def : Handle {
+  let name = "ol_program_handle_t";
+  let desc = "Handle of Program object";
+}
+
+def : Handle {
+  let name = "ol_kernel_handle_t";
+  let desc = "Handle of program's Kernel object";
+}
+
+def : Handle {
+  let name = "ol_queue_handle_t";
+  let desc = "Handle of a queue object";
+}
+
+def : Handle {
+  let name = "ol_native_handle_t";
+  let desc = "Handle of a native object";
+}
+
+def : Handle {
+  let name = "ol_sampler_handle_t";
+  let desc = "Handle of a Sampler object";
+}
+
+def : Handle {
+  let name = "ol_mem_handle_t";
+  let desc = "Handle of memory object which can either be buffer or image";
+}
+
+def : Handle {
+  let name = "ol_physical_mem_handle_t";
+  let desc = "Handle of physical memory object";
+}
+
+def : Macro {
+  let name = "OL_BIT( _i )";
+  let desc = "Generic macro for enumerator bit masks";
+  let value = "( 1 << _i )";
+}
+
+def : Enum {
+  let name = "ol_result_t";
+  let desc = "Defines Return/Error codes";
+  let etors =[
+    Etor<"SUCCESS", "Success">,
+    Etor<"ERROR_INVALID_OPERATION", "Invalid operation">,
+    Etor<"ERROR_INVALID_QUEUE_PROPERTIES", "Invalid queue properties">,
+    Etor<"ERROR_INVALID_QUEUE", "Invalid queue">,
+    Etor<"ERROR_INVALID_VALUE", "Invalid Value">,
+    Etor<"ERROR_INVALID_CONTEXT", "Invalid context">,
+    Etor<"ERROR_INVALID_PLATFORM", "Invalid platform">,
+    Etor<"ERROR_INVALID_BINARY", "Invalid binary">,
+    Etor<"ERROR_INVALID_PROGRAM", "Invalid program">,
+    Etor<"ERROR_INVALID_SAMPLER", "Invalid sampler">,
+    Etor<"ERROR_INVALID_BUFFER_SIZE", "Invalid buffer size">,
+    Etor<"ERROR_INVALID_MEM_OBJECT", "Invalid memory object">,
+    Etor<"ERROR_INVALID_EVENT", "Invalid event">,
+    Etor<"ERROR_INVALID_EVENT_WAIT_LIST", "Returned when the event wait list or the events in the wait list are invalid.">,
+    Etor<"ERROR_MISALIGNED_SUB_BUFFER_OFFSET", "Misaligned sub buffer offset">,
+    Etor<"ERROR_INVALID_WORK_GROUP_SIZE", "Invalid work group size">,
+    Etor<"ERROR_COMPILER_NOT_AVAILABLE", "Compiler not available">,
+    Etor<"ERROR_PROFILING_INFO_NOT_AVAILABLE", "Profiling info not available">,
+    Etor<"ERROR_DEVICE_NOT_FOUND", "Device not found">,
+    Etor<"ERROR_INVALID_DEVICE", "Invalid device">,
+    Etor<"ERROR_DEVICE_LOST", "Device hung, reset, was removed, or adapter update occurred">,
+    Etor<"ERROR_DEVICE_REQUIRES_RESET", "Device requires a reset">,
+    Etor<"ERROR_DEVICE_IN_LOW_POWER_STATE", "Device currently in low power state">,
+    Etor<"ERROR_DEVICE_PARTITION_FAILED", "Device partitioning failed">,
+    Etor<"ERROR_INVALID_DEVICE_PARTITION_COUNT", "Invalid counts provided with OL_DEVICE_PARTITION_BY_COUNTS">,
+    Etor<"ERROR_INVALID_WORK_ITEM_SIZE", "Invalid work item size">,
+    Etor<"ERROR_INVALID_WORK_DIMENSION", "Invalid work dimension">,
+    Etor<"ERROR_INVALID_KERNEL_ARGS", "Invalid kernel args">,
+    Etor<"ERROR_INVALID_KERNEL", "Invalid kernel">,
+    Etor<"ERROR_INVALID_KERNEL_NAME", "[Validation] kernel name is not found in the program">,
+    Etor<"ERROR_INVALID_KERNEL_ARGUMENT_INDEX", "[Validation] kernel argument index is not valid for kernel">,
+    Etor<"ERROR_INVALID_KERNEL_ARGUMENT_SIZE", "[Validation] kernel argument size does not match kernel">,
+    Etor<"ERROR_INVALID_KERNEL_ATTRIBUTE_VALUE", "[Validation] value of kernel attribute is not valid for the kernel or device">,
+    Etor<"ERROR_INVALID_IMAGE_SIZE", "Invalid image size">,
+    Etor<"ERROR_INVALID_IMAGE_FORMAT_DESCRIPTOR", "Invalid image format descriptor">,
+    Etor<"ERROR_IMAGE_FORMAT_NOT_SUPPORTED", "Image format not supported">,
+    Etor<"ERROR_MEM_OBJECT_ALLOCATION_FAILURE", "Memory object allocation failure">,
+    Etor<"ERROR_INVALID_PROGRAM_EXECUTABLE", "Program object parameter is invalid.">,
+    Etor<"ERROR_UNINITIALIZED", "[Validation] adapter is not initialized or specific entry-point is not implemented">,
+    Etor<"ERROR_OUT_OF_HOST_MEMORY", "Insufficient host memory to satisfy call">,
+    Etor<"ERROR_OUT_OF_DEVICE_MEMORY", "Insufficient device memory to satisfy call">,
+    Etor<"ERROR_OUT_OF_RESOURCES", "Out of resources">,
+    Etor<"ERROR_PROGRAM_BUILD_FAILURE", "Error occurred when building program, see build log for details">,
+    Etor<"ERROR_PROGRAM_LINK_FAILURE", "Error occurred when linking programs, see build log for details">,
+    Etor<"ERROR_UNSUPPORTED_VERSION", "[Validation] generic error code for unsupported versions">,
+    Etor<"ERROR_UNSUPPORTED_FEATURE", "[Validation] generic error code for unsupported features">,
+    Etor<"ERROR_INVALID_ARGUMENT", "[Validation] generic error code for invalid arguments">,
+    Etor<"ERROR_INVALID_NULL_HANDLE", "[Validation] handle argument is not valid">,
+    Etor<"ERROR_HANDLE_OBJECT_IN_USE", "[Validation] object pointed to by handle still in-use by device">,
+    Etor<"ERROR_INVALID_NULL_POINTER", "[Validation] pointer argument may not be nullptr">,
+    Etor<"ERROR_INVALID_SIZE", "[Validation] invalid size or dimensions (e.g., must not be zero, or is out of bounds)">,
+    Etor<"ERROR_UNSUPPORTED_SIZE", "[Validation] size argument is not supported by the device (e.g., too large)">,
+    Etor<"ERROR_UNSUPPORTED_ALIGNMENT", "[Validation] alignment argument is not supported by the device (e.g., too small)">,
+    Etor<"ERROR_INVALID_SYNCHRONIZATION_OBJECT", "[Validation] synchronization object in invalid state">,
+    Etor<"ERROR_INVALID_ENUMERATION", "[Validation] enumerator argument is not valid">,
+    Etor<"ERROR_UNSUPPORTED_ENUMERATION", "[Validation] enumerator argument is not supported by the device">,
+    Etor<"ERROR_UNSUPPORTED_IMAGE_FORMAT", "[Validation] image format is not supported by the device">,
+    Etor<"ERROR_INVALID_NATIVE_BINARY", "[Validation] native binary is not supported by the device">,
+    Etor<"ERROR_INVALID_GLOBAL_NAME", "[Validation] global variable is not found in the program">,
+    Etor<"ERROR_INVALID_FUNCTION_NAME", "[Validation] function name is not found in the program">,
+    Etor<"ERROR_INVALID_GROUP_SIZE_DIMENSION", "[Validation] group size dimension is not valid for the kernel or device">,
+    Etor<"ERROR_INVALID_GLOBAL_WIDTH_DIMENSION", "[Validation] global width dimension is not valid for the kernel or device">,
+    Etor<"ERROR_PROGRAM_UNLINKED", "[Validation] compiled program or program with imports needs to be linked before kernels can be created from it.">,
+    Etor<"ERROR_OVERLAPPING_REGIONS", "[Validation] copy operations do not support overlapping regions of memory">,
+    Etor<"ERROR_INVALID_HOST_PTR", "Invalid host pointer">,
+    Etor<"ERROR_INVALID_USM_SIZE", "Invalid USM size">,
+    Etor<"ERROR_OBJECT_ALLOCATION_FAILURE", "Objection allocation failure">,
+    Etor<"ERROR_ADAPTER_SPECIFIC", "An adapter specific warning/error has been reported and can be retrieved via the urPlatformGetLastError entry point.">,
+    Etor<"ERROR_LAYER_NOT_PRESENT", "A requested layer was not found by the loader.">,
+    Etor<"ERROR_IN_EVENT_LIST_EXEC_STATUS", "An event in the provided wait list has OL_EVENT_STATUS_ERROR.">,
+    Etor<"ERROR_UNKNOWN", "Unknown or internal error">
+  ];
+}
+
+def : Struct {
+  let name = "ol_base_properties_t";
+  let desc = "Base for all properties types";
+  let members = [
+    StructMember<"ol_structure_type_t", "stype", "[in] type of this structure">,
+    StructMember<"void*", "pNext", "[in,out][optional] pointer to extension-specific structure">
+  ];
+}
+
+def : Struct {
+  let name = "ol_base_desc_t";
+  let desc = "Base for all descriptor types";
+  let members = [
+    StructMember<"ol_structure_type_t", "stype", "[in] type of this structure">,
+    StructMember<"const void*", "pNext", "[in][optional] pointer to extension-specific structure">
+  ];
+}
+
+def : Struct {
+  let name = "ol_rect_offset_t";
+  let desc = "3D offset argument passed to buffer rect operations";
+  let members = [
+    StructMember<"uint64_t", "x", "[in] x offset (bytes)">,
+    StructMember<"uint64_t", "y", "[in] y offset (scalar)">,
+    StructMember<"uint64_t", "z", "[in] z offset (scalar)">
+  ];
+}
+
+def : Struct {
+  let name = "ol_rect_region_t";
+  let desc = "3D region argument passed to buffer rect operations";
+  let members = [
+    StructMember<"uint64_t", "width", "[in] width (bytes)">,
+    StructMember<"uint64_t", "height", "[in] height (scalar)">,
+    StructMember<"uint64_t", "depth", "[in] scalar (scalar)">
+  ];
+}
+
+def : Enum {
+  let name = "ol_queue_info_t";
+  let desc = "Query queue info";
+    let is_typed = 1;
+  let etors =[
+    Etor<"CONTEXT", "[ol_context_handle_t] context associated with this queue.">,
+    Etor<"DEVICE", "[ol_device_handle_t] device associated with this queue.">,
+    Etor<"DEVICE_DEFAULT", "[ol_queue_handle_t] the current default queue of the underlying device.">,
+    Etor<"FLAGS", "[ol_queue_flags_t] the properties associated with ol_queue_properties_t::flags.">,
+    Etor<"REFERENCE_COUNT", [{[uint32_t] Reference count of the queue object.
+The reference count returned should be considered immediately stale. ...
[truncated]

``````````

</details>


https://github.com/llvm/llvm-project/pull/88923


More information about the llvm-commits mailing list