xref: /llvm-project/offload/liboffload/src/Helpers.hpp (revision fd3907ccb583df99e9c19d2fe84e4e7c52d75de9)
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 
17 #include <cstring>
18 
19 template <typename T, typename Assign>
20 ol_errc_t getInfoImpl(size_t ParamValueSize, void *ParamValue,
21                       size_t *ParamValueSizeRet, T Value, size_t ValueSize,
22                       Assign &&AssignFunc) {
23   if (!ParamValue && !ParamValueSizeRet) {
24     return OL_ERRC_INVALID_NULL_POINTER;
25   }
26 
27   if (ParamValue != nullptr) {
28     if (ParamValueSize < ValueSize) {
29       return OL_ERRC_INVALID_SIZE;
30     }
31     AssignFunc(ParamValue, Value, ValueSize);
32   }
33 
34   if (ParamValueSizeRet != nullptr) {
35     *ParamValueSizeRet = ValueSize;
36   }
37 
38   return OL_ERRC_SUCCESS;
39 }
40 
41 template <typename T>
42 ol_errc_t getInfo(size_t ParamValueSize, void *ParamValue,
43                   size_t *ParamValueSizeRet, T Value) {
44   auto Assignment = [](void *ParamValue, T Value, size_t) {
45     *static_cast<T *>(ParamValue) = Value;
46   };
47 
48   return getInfoImpl(ParamValueSize, ParamValue, ParamValueSizeRet, Value,
49                      sizeof(T), Assignment);
50 }
51 
52 template <typename T>
53 ol_errc_t getInfoArray(size_t array_length, size_t ParamValueSize,
54                        void *ParamValue, size_t *ParamValueSizeRet,
55                        const T *Value) {
56   return getInfoImpl(ParamValueSize, ParamValue, ParamValueSizeRet, Value,
57                      array_length * sizeof(T), memcpy);
58 }
59 
60 template <>
61 inline ol_errc_t getInfo<const char *>(size_t ParamValueSize, void *ParamValue,
62                                        size_t *ParamValueSizeRet,
63                                        const char *Value) {
64   return getInfoArray(strlen(Value) + 1, ParamValueSize, ParamValue,
65                       ParamValueSizeRet, Value);
66 }
67 
68 class ReturnHelper {
69 public:
70   ReturnHelper(size_t ParamValueSize, void *ParamValue,
71                size_t *ParamValueSizeRet)
72       : ParamValueSize(ParamValueSize), ParamValue(ParamValue),
73         ParamValueSizeRet(ParamValueSizeRet) {}
74 
75   // A version where in/out info size is represented by a single pointer
76   // to a value which is updated on return
77   ReturnHelper(size_t *ParamValueSize, void *ParamValue)
78       : ParamValueSize(*ParamValueSize), ParamValue(ParamValue),
79         ParamValueSizeRet(ParamValueSize) {}
80 
81   // Scalar return Value
82   template <class T> ol_errc_t operator()(const T &t) {
83     return getInfo(ParamValueSize, ParamValue, ParamValueSizeRet, t);
84   }
85 
86   // Array return Value
87   template <class T> ol_errc_t operator()(const T *t, size_t s) {
88     return getInfoArray(s, ParamValueSize, ParamValue, ParamValueSizeRet, t);
89   }
90 
91 protected:
92   size_t ParamValueSize;
93   void *ParamValue;
94   size_t *ParamValueSizeRet;
95 };
96