1//===- helpers.hpp- GetInfo return helpers for the new LLVM/Offload API ---===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// The getInfo*/ReturnHelper facilities provide shortcut way of writing return
10// data + size for the various getInfo APIs. Based on the equivalent
11// implementations in Unified Runtime.
12//
13//===----------------------------------------------------------------------===//
14
15#include "OffloadAPI.h"
16#include "OffloadError.h"
17#include "llvm/Support/Error.h"
18
19#include <cstring>
20
21template <typename T, typename Assign>
22llvm::Error getInfoImpl(size_t ParamValueSize, void *ParamValue,
23 size_t *ParamValueSizeRet, T Value, size_t ValueSize,
24 Assign &&AssignFunc) {
25 if (!ParamValue && !ParamValueSizeRet) {
26 return error::createOffloadError(error::ErrorCode::INVALID_NULL_POINTER,
27 "value and size outputs are nullptr");
28 }
29
30 if (ParamValue != nullptr) {
31 if (ParamValueSize < ValueSize) {
32 return error::createOffloadError(error::ErrorCode::INVALID_SIZE,
33 "provided size is invalid");
34 }
35 AssignFunc(ParamValue, Value, ValueSize);
36 }
37
38 if (ParamValueSizeRet != nullptr) {
39 *ParamValueSizeRet = ValueSize;
40 }
41
42 return llvm::Error::success();
43}
44
45template <typename T>
46llvm::Error getInfo(size_t ParamValueSize, void *ParamValue,
47 size_t *ParamValueSizeRet, T Value) {
48 auto Assignment = [](void *ParamValue, T Value, size_t) {
49 *static_cast<T *>(ParamValue) = Value;
50 };
51
52 return getInfoImpl(ParamValueSize, ParamValue, ParamValueSizeRet, Value,
53 sizeof(T), Assignment);
54}
55
56template <typename T>
57llvm::Error getInfoArray(size_t array_length, size_t ParamValueSize,
58 void *ParamValue, size_t *ParamValueSizeRet,
59 const T *Value) {
60 return getInfoImpl(ParamValueSize, ParamValue, ParamValueSizeRet, Value,
61 array_length * sizeof(T), memcpy);
62}
63
64llvm::Error getInfoString(size_t ParamValueSize, void *ParamValue,
65 size_t *ParamValueSizeRet, llvm::StringRef Value) {
66 return getInfoArray(array_length: Value.size() + 1, ParamValueSize, ParamValue,
67 ParamValueSizeRet, Value: Value.data());
68}
69
70class InfoWriter {
71public:
72 InfoWriter(size_t Size, void *Target, size_t *SizeRet)
73 : Size(Size), Target(Target), SizeRet(SizeRet) {};
74 InfoWriter() = delete;
75 InfoWriter(InfoWriter &) = delete;
76 ~InfoWriter() = default;
77
78 template <typename T> llvm::Error write(llvm::Expected<T> &&Val) {
79 if (Val)
80 return getInfo(Size, Target, SizeRet, *Val);
81 return Val.takeError();
82 }
83
84 template <typename T>
85 llvm::Error writeArray(llvm::Expected<T> &&Val, size_t Elems) {
86 if (Val)
87 return getInfoArray(Elems, Size, Target, SizeRet, *Val);
88 return Val.takeError();
89 }
90
91 llvm::Error writeString(llvm::Expected<llvm::StringRef> &&Val) {
92 if (Val)
93 return getInfoString(ParamValueSize: Size, ParamValue: Target, ParamValueSizeRet: SizeRet, Value: *Val);
94 return Val.takeError();
95 }
96
97private:
98 size_t Size;
99 void *Target;
100 size_t *SizeRet;
101};
102

source code of offload/liboffload/src/Helpers.hpp