1 //===-------- State.h - OpenMP State & ICV interface ------------- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
10 //===----------------------------------------------------------------------===//
12 #ifndef OMPTARGET_STATE_H
13 #define OMPTARGET_STATE_H
18 #pragma omp declare target
24 inline constexpr uint32_t SharedScratchpadSize
= SHARED_SCRATCHPAD_SIZE
;
26 /// Initialize the state machinery. Must be called by all threads.
27 void init(bool IsSPMD
);
43 void enterDataEnvironment();
46 void exitDataEnvironment();
49 struct DateEnvironmentRAII
{
50 DateEnvironmentRAII() { enterDataEnvironment(); }
51 ~DateEnvironmentRAII() { exitDataEnvironment(); }
55 void resetStateForThread(uint32_t TId
);
57 uint32_t &lookup32(ValueKind VK
, bool IsReadonly
);
58 void *&lookupPtr(ValueKind VK
, bool IsReadonly
);
60 /// A class without actual state used to provide a nice interface to lookup and
61 /// update ICV values we can declare in global scope.
62 template <typename Ty
, ValueKind Kind
> struct Value
{
63 __attribute__((flatten
, always_inline
)) operator Ty() {
64 return lookup(/* IsReadonly */ true);
67 __attribute__((flatten
, always_inline
)) Value
&operator=(const Ty
&Other
) {
72 __attribute__((flatten
, always_inline
)) Value
&operator++() {
77 __attribute__((flatten
, always_inline
)) Value
&operator--() {
83 Ty
&lookup(bool IsReadonly
) {
84 Ty
&t
= lookup32(Kind
, IsReadonly
);
88 Ty
&inc(int UpdateVal
) {
89 return (lookup(/* IsReadonly */ false) += UpdateVal
);
92 Ty
&set(Ty UpdateVal
) { return (lookup(/* IsReadonly */ false) = UpdateVal
); }
94 template <typename VTy
, typename Ty2
> friend struct ValueRAII
;
97 /// A mookup class without actual state used to provide
98 /// a nice interface to lookup and update ICV values
99 /// we can declare in global scope.
100 template <typename Ty
, ValueKind Kind
> struct PtrValue
{
101 __attribute__((flatten
, always_inline
)) operator Ty() {
102 return lookup(/* IsReadonly */ true);
105 __attribute__((flatten
, always_inline
)) PtrValue
&operator=(const Ty Other
) {
111 Ty
&lookup(bool IsReadonly
) { return lookupPtr(Kind
, IsReadonly
); }
113 Ty
&set(Ty UpdateVal
) { return (lookup(/* IsReadonly */ false) = UpdateVal
); }
115 template <typename VTy
, typename Ty2
> friend struct ValueRAII
;
118 template <typename VTy
, typename Ty
> struct ValueRAII
{
119 ValueRAII(VTy
&V
, Ty NewValue
, Ty OldValue
, bool Active
)
120 : Ptr(Active
? V
.lookup(/* IsReadonly */ false) : Val
), Val(OldValue
),
124 ASSERT(Ptr
== OldValue
&& "ValueRAII initialization with wrong old value!");
139 inline state::Value
<uint32_t, state::VK_RunSchedChunk
> RunSchedChunk
;
142 inline state::Value
<uint32_t, state::VK_ParallelTeamSize
> ParallelTeamSize
;
145 inline state::PtrValue
<ParallelRegionFnTy
, state::VK_ParallelRegionFn
>
148 void runAndCheckState(void(Func(void)));
150 void assumeInitialState(bool IsSPMD
);
157 inline state::Value
<uint32_t, state::VK_NThreads
> NThreads
;
160 inline state::Value
<uint32_t, state::VK_Level
> Level
;
162 /// The `active-level` describes which of the parallel level counted with the
163 /// `level-var` is active. There can only be one.
165 /// active-level-var is 1, if ActiveLevelVar is not 0, otherweise it is 0.
166 inline state::Value
<uint32_t, state::VK_ActiveLevel
> ActiveLevel
;
169 inline state::Value
<uint32_t, state::VK_MaxActiveLevels
> MaxActiveLevels
;
172 inline state::Value
<uint32_t, state::VK_RunSched
> RunSched
;
178 /// Alloca \p Size bytes in shared memory, if possible, for \p Reason.
180 /// Note: See the restrictions on __kmpc_alloc_shared for proper usage.
181 void *allocShared(uint64_t Size
, const char *Reason
);
183 /// Free \p Ptr, alloated via allocShared, for \p Reason.
185 /// Note: See the restrictions on __kmpc_free_shared for proper usage.
186 void freeShared(void *Ptr
, uint64_t Bytes
, const char *Reason
);
188 /// Alloca \p Size bytes in global memory, if possible, for \p Reason.
189 void *allocGlobal(uint64_t Size
, const char *Reason
);
191 /// Return a pointer to the dynamic shared memory buffer.
192 void *getDynamicBuffer();
194 /// Free \p Ptr, alloated via allocGlobal, for \p Reason.
195 void freeGlobal(void *Ptr
, const char *Reason
);
197 } // namespace memory
201 #pragma omp end declare target