102 lines · c
1//===-- OpenMP/Requirements.h - User required requirements -----*- 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-exception6//7//===----------------------------------------------------------------------===//8//9// Handling of the `omp requires` directive, e.g., requiring unified shared10// memory.11//12//===----------------------------------------------------------------------===//13 14#ifndef OMPTARGET_OPENMP_REQUIREMENTS_H15#define OMPTARGET_OPENMP_REQUIREMENTS_H16 17#include "Shared/Debug.h"18 19#include "llvm/ADT/StringRef.h"20 21#include <cassert>22#include <cstdint>23 24enum OpenMPOffloadingRequiresDirFlags : int64_t {25 /// flag undefined.26 OMP_REQ_UNDEFINED = 0x000,27 /// no requires directive present.28 OMP_REQ_NONE = 0x001,29 /// reverse_offload clause.30 OMP_REQ_REVERSE_OFFLOAD = 0x002,31 /// unified_address clause.32 OMP_REQ_UNIFIED_ADDRESS = 0x004,33 /// unified_shared_memory clause.34 OMP_REQ_UNIFIED_SHARED_MEMORY = 0x008,35 /// dynamic_allocators clause.36 OMP_REQ_DYNAMIC_ALLOCATORS = 0x010,37 /// Auto zero-copy extension:38 /// when running on an APU, the GPU plugin may decide to39 /// run in zero-copy even though the user did not program40 /// their application with unified_shared_memory requirement.41 OMPX_REQ_AUTO_ZERO_COPY = 0x02042};43 44class RequirementCollection {45 int64_t SetFlags = OMP_REQ_UNDEFINED;46 47 /// Check consistency between different requires flags (from different48 /// translation units).49 void checkConsistency(int64_t NewFlags, int64_t SetFlags,50 OpenMPOffloadingRequiresDirFlags Flag,51 llvm::StringRef Clause) {52 if ((SetFlags & Flag) != (NewFlags & Flag)) {53 FATAL_MESSAGE(2, "'#pragma omp requires %s' not used consistently!",54 Clause.data());55 }56 }57 58public:59 /// Register \p NewFlags as part of the user requirements.60 void addRequirements(int64_t NewFlags) {61 // TODO: add more elaborate check.62 // Minimal check: only set requires flags if previous value63 // is undefined. This ensures that only the first call to this64 // function will set the requires flags. All subsequent calls65 // will be checked for compatibility.66 assert(NewFlags != OMP_REQ_UNDEFINED &&67 "illegal undefined flag for requires directive!");68 if (SetFlags == OMP_REQ_UNDEFINED) {69 SetFlags = NewFlags;70 return;71 }72 73 // Auto zero-copy is only valid when no other requirement has been set74 // and it is computed at device initialization time, after the requirement75 // flag has already been set to OMP_REQ_NONE.76 if (SetFlags == OMP_REQ_NONE && NewFlags == OMPX_REQ_AUTO_ZERO_COPY) {77 SetFlags = NewFlags;78 return;79 }80 81 // If multiple compilation units are present enforce82 // consistency across all of them for require clauses:83 // - reverse_offload84 // - unified_address85 // - unified_shared_memory86 // - dynamic_allocators87 checkConsistency(NewFlags, SetFlags, OMP_REQ_REVERSE_OFFLOAD,88 "reverse_offload");89 checkConsistency(NewFlags, SetFlags, OMP_REQ_UNIFIED_ADDRESS,90 "unified_address");91 checkConsistency(NewFlags, SetFlags, OMP_REQ_UNIFIED_SHARED_MEMORY,92 "unified_shared_memory");93 checkConsistency(NewFlags, SetFlags, OMP_REQ_DYNAMIC_ALLOCATORS,94 "dynamic_allocators");95 }96 97 /// Return the user provided requirements.98 int64_t getRequirements() const { return SetFlags; }99};100 101#endif // OMPTARGET_OPENMP_DEVICE_REQUIREMENTS_H102