//===---------- Types.h - OpenMP types ---------------------------- C++ -*-===// // // 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 // //===----------------------------------------------------------------------===// // // //===----------------------------------------------------------------------===// #ifndef OMPTARGET_TYPES_H #define OMPTARGET_TYPES_H /// Base type declarations for freestanding mode /// ///{ using int8_t = char; using uint8_t = unsigned char; using int16_t = short; using uint16_t = unsigned short; using int32_t = int; using uint32_t = unsigned int; using int64_t = long; using uint64_t = unsigned long; static_assert(sizeof(int8_t) == 1, "type size mismatch"); static_assert(sizeof(uint8_t) == 1, "type size mismatch"); static_assert(sizeof(int16_t) == 2, "type size mismatch"); static_assert(sizeof(uint16_t) == 2, "type size mismatch"); static_assert(sizeof(int32_t) == 4, "type size mismatch"); static_assert(sizeof(uint32_t) == 4, "type size mismatch"); static_assert(sizeof(int64_t) == 8, "type size mismatch"); static_assert(sizeof(uint64_t) == 8, "type size mismatch"); ///} enum omp_proc_bind_t { omp_proc_bind_false = 0, omp_proc_bind_true = 1, omp_proc_bind_master = 2, omp_proc_bind_close = 3, omp_proc_bind_spread = 4 }; enum omp_sched_t { omp_sched_static = 1, /* chunkSize >0 */ omp_sched_dynamic = 2, /* chunkSize >0 */ omp_sched_guided = 3, /* chunkSize >0 */ omp_sched_auto = 4, /* no chunkSize */ }; enum kmp_sched_t { kmp_sched_static_chunk = 33, kmp_sched_static_nochunk = 34, kmp_sched_dynamic = 35, kmp_sched_guided = 36, kmp_sched_runtime = 37, kmp_sched_auto = 38, kmp_sched_static_balanced_chunk = 45, kmp_sched_static_ordered = 65, kmp_sched_static_nochunk_ordered = 66, kmp_sched_dynamic_ordered = 67, kmp_sched_guided_ordered = 68, kmp_sched_runtime_ordered = 69, kmp_sched_auto_ordered = 70, kmp_sched_distr_static_chunk = 91, kmp_sched_distr_static_nochunk = 92, kmp_sched_distr_static_chunk_sched_static_chunkone = 93, kmp_sched_default = kmp_sched_static_nochunk, kmp_sched_unordered_first = kmp_sched_static_chunk, kmp_sched_unordered_last = kmp_sched_auto, kmp_sched_ordered_first = kmp_sched_static_ordered, kmp_sched_ordered_last = kmp_sched_auto_ordered, kmp_sched_distribute_first = kmp_sched_distr_static_chunk, kmp_sched_distribute_last = kmp_sched_distr_static_chunk_sched_static_chunkone, /* Support for OpenMP 4.5 monotonic and nonmonotonic schedule modifiers. * Since we need to distinguish the three possible cases (no modifier, * monotonic modifier, nonmonotonic modifier), we need separate bits for * each modifier. The absence of monotonic does not imply nonmonotonic, * especially since 4.5 says that the behaviour of the "no modifier" case * is implementation defined in 4.5, but will become "nonmonotonic" in 5.0. * * Since we're passing a full 32 bit value, we can use a couple of high * bits for these flags; out of paranoia we avoid the sign bit. * * These modifiers can be or-ed into non-static schedules by the compiler * to pass the additional information. They will be stripped early in the * processing in __kmp_dispatch_init when setting up schedules, so * most of the code won't ever see schedules with these bits set. */ kmp_sched_modifier_monotonic = (1 << 29), /**< Set if the monotonic schedule modifier was present */ kmp_sched_modifier_nonmonotonic = (1 << 30), /**< Set if the nonmonotonic schedule modifier was present */ #define SCHEDULE_WITHOUT_MODIFIERS(s) \ (enum kmp_sched_t)( \ (s) & ~(kmp_sched_modifier_nonmonotonic | kmp_sched_modifier_monotonic)) #define SCHEDULE_HAS_MONOTONIC(s) (((s)&kmp_sched_modifier_monotonic) != 0) #define SCHEDULE_HAS_NONMONOTONIC(s) \ (((s)&kmp_sched_modifier_nonmonotonic) != 0) #define SCHEDULE_HAS_NO_MODIFIERS(s) \ (((s) & (kmp_sched_modifier_nonmonotonic | kmp_sched_modifier_monotonic)) == \ 0) }; struct TaskDescriptorTy; using TaskFnTy = int32_t (*)(int32_t global_tid, TaskDescriptorTy *taskDescr); struct TaskDescriptorTy { void *Payload; TaskFnTy TaskFn; }; #pragma omp begin declare variant match(device = {arch(amdgcn)}) using LaneMaskTy = uint64_t; #pragma omp end declare variant #pragma omp begin declare variant match( \ device = {arch(amdgcn)}, implementation = {extension(match_none)}) using LaneMaskTy = uint64_t; #pragma omp end declare variant namespace lanes { enum : LaneMaskTy { All = ~(LaneMaskTy)0 }; } // namespace lanes /// The ident structure that describes a source location. The struct is /// identical to the one in the kmp.h file. We maintain the same data structure /// for compatibility. struct IdentTy { int32_t reserved_1; /**< might be used in Fortran; see above */ int32_t flags; /**< also f.flags; KMP_IDENT_xxx flags; KMP_IDENT_KMPC identifies this union member */ int32_t reserved_2; /**< not really used in Fortran any more; see above */ int32_t reserved_3; /**< source[4] in Fortran, do not use for C++ */ char const *psource; /**< String describing the source location. The string is composed of semi-colon separated fields which describe the source file, the function and a pair of line numbers that delimit the construct. */ }; using __kmpc_impl_lanemask_t = LaneMaskTy; using ParallelRegionFnTy = void *; using CriticalNameTy = int32_t[8]; struct omp_lock_t { void *Lock; }; using InterWarpCopyFnTy = void (*)(void *src, int32_t warp_num); using ShuffleReductFnTy = void (*)(void *rhsData, int16_t lane_id, int16_t lane_offset, int16_t shortCircuit); using ListGlobalFnTy = void (*)(void *buffer, int idx, void *reduce_data); /// Macros for allocating variables in different address spaces. ///{ // Follows the pattern in interface.h typedef enum omp_allocator_handle_t { omp_null_allocator = 0, omp_default_mem_alloc = 1, omp_large_cap_mem_alloc = 2, omp_const_mem_alloc = 3, omp_high_bw_mem_alloc = 4, omp_low_lat_mem_alloc = 5, omp_cgroup_mem_alloc = 6, omp_pteam_mem_alloc = 7, omp_thread_mem_alloc = 8, KMP_ALLOCATOR_MAX_HANDLE = ~(0U) } omp_allocator_handle_t; enum OMPTgtExecModeFlags : int8_t { OMP_TGT_EXEC_MODE_GENERIC = 1 << 0, OMP_TGT_EXEC_MODE_SPMD = 1 << 1, }; #define __PRAGMA(STR) _Pragma(#STR) #define OMP_PRAGMA(STR) __PRAGMA(omp STR) #define SHARED(NAME) \ NAME [[clang::loader_uninitialized]]; \ OMP_PRAGMA(allocate(NAME) allocator(omp_pteam_mem_alloc)) // TODO: clang should use address space 5 for omp_thread_mem_alloc, but right // now that's not the case. #define THREAD_LOCAL(NAME) \ NAME [[clang::loader_uninitialized, clang::address_space(5)]] // TODO: clang should use address space 4 for omp_const_mem_alloc, maybe it // does? #define CONSTANT(NAME) \ NAME [[clang::loader_uninitialized, clang::address_space(4)]] ///} #endif