xref: /llvm-project/offload/include/Shared/Utils.h (revision f53cb84df6b80458cb4d5ab7398a590356a3a952)
1 //===-- Shared/Utils.h - Target independent OpenMP target RTL -- C++ ------===//
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 // Routines and classes used to provide useful functionalities for the host and
10 // the device.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #ifndef OMPTARGET_SHARED_UTILS_H
15 #define OMPTARGET_SHARED_UTILS_H
16 
17 #include <stdint.h>
18 
19 namespace utils {
20 
21 /// Return the difference (in bytes) between \p Begin and \p End.
22 template <typename Ty = char>
23 auto getPtrDiff(const void *End, const void *Begin) {
24   return reinterpret_cast<const Ty *>(End) -
25          reinterpret_cast<const Ty *>(Begin);
26 }
27 
28 /// Return \p Ptr advanced by \p Offset bytes.
29 template <typename Ty1, typename Ty2> Ty1 *advancePtr(Ty1 *Ptr, Ty2 Offset) {
30   return (Ty1 *)(const_cast<char *>((const char *)(Ptr)) + Offset);
31 }
32 
33 /// Return \p V aligned "upwards" according to \p Align.
34 template <typename Ty1, typename Ty2> inline Ty1 alignPtr(Ty1 V, Ty2 Align) {
35   return reinterpret_cast<Ty1>(((uintptr_t(V) + Align - 1) / Align) * Align);
36 }
37 /// Return \p V aligned "downwards" according to \p Align.
38 template <typename Ty1, typename Ty2> inline Ty1 alignDown(Ty1 V, Ty2 Align) {
39   return V - V % Align;
40 }
41 
42 /// Round up \p V to a \p Boundary.
43 template <typename Ty> inline Ty roundUp(Ty V, Ty Boundary) {
44   return alignPtr(V, Boundary);
45 }
46 
47 /// Return the first bit set in \p V.
48 inline uint32_t ffs(uint32_t V) {
49   static_assert(sizeof(int) == sizeof(uint32_t), "type size mismatch");
50   return __builtin_ffs(V);
51 }
52 
53 /// Return the first bit set in \p V.
54 inline uint32_t ffs(uint64_t V) {
55   static_assert(sizeof(long) == sizeof(uint64_t), "type size mismatch");
56   return __builtin_ffsl(V);
57 }
58 
59 /// Return the number of bits set in \p V.
60 inline uint32_t popc(uint32_t V) {
61   static_assert(sizeof(int) == sizeof(uint32_t), "type size mismatch");
62   return __builtin_popcount(V);
63 }
64 
65 /// Return the number of bits set in \p V.
66 inline uint32_t popc(uint64_t V) {
67   static_assert(sizeof(long) == sizeof(uint64_t), "type size mismatch");
68   return __builtin_popcountl(V);
69 }
70 
71 } // namespace utils
72 
73 #endif // OMPTARGET_SHARED_UTILS_H
74