]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/include/clang/Basic/SyncScope.h
Merge clang 7.0.1 and several follow-up changes
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / include / clang / Basic / SyncScope.h
1 //===--- SyncScope.h - Atomic synchronization scopes ------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 ///
10 /// \file
11 /// Provides definitions for the atomic synchronization scopes.
12 ///
13 //===----------------------------------------------------------------------===//
14
15 #ifndef LLVM_CLANG_BASIC_SYNCSCOPE_H
16 #define LLVM_CLANG_BASIC_SYNCSCOPE_H
17
18 #include "clang/Basic/LangOptions.h"
19 #include "llvm/ADT/ArrayRef.h"
20 #include "llvm/ADT/StringRef.h"
21 #include <memory>
22
23 namespace clang {
24
25 /// Defines synch scope values used internally by clang.
26 ///
27 /// The enum values start from 0 and are contiguous. They are mainly used for
28 /// enumerating all supported synch scope values and mapping them to LLVM
29 /// synch scopes. Their numerical values may be different from the corresponding
30 /// synch scope enums used in source languages.
31 ///
32 /// In atomic builtin and expressions, language-specific synch scope enums are
33 /// used. Currently only OpenCL memory scope enums are supported and assumed
34 /// to be used by all languages. However, in the future, other languages may
35 /// define their own set of synch scope enums. The language-specific synch scope
36 /// values are represented by class AtomicScopeModel and its derived classes.
37 ///
38 /// To add a new enum value:
39 ///   Add the enum value to enum class SyncScope.
40 ///   Update enum value Last if necessary.
41 ///   Update getAsString.
42 ///
43 enum class SyncScope {
44   OpenCLWorkGroup,
45   OpenCLDevice,
46   OpenCLAllSVMDevices,
47   OpenCLSubGroup,
48   Last = OpenCLSubGroup
49 };
50
51 inline llvm::StringRef getAsString(SyncScope S) {
52   switch (S) {
53   case SyncScope::OpenCLWorkGroup:
54     return "opencl_workgroup";
55   case SyncScope::OpenCLDevice:
56     return "opencl_device";
57   case SyncScope::OpenCLAllSVMDevices:
58     return "opencl_allsvmdevices";
59   case SyncScope::OpenCLSubGroup:
60     return "opencl_subgroup";
61   }
62   llvm_unreachable("Invalid synch scope");
63 }
64
65 /// Defines the kind of atomic scope models.
66 enum class AtomicScopeModelKind { None, OpenCL };
67
68 /// Defines the interface for synch scope model.
69 class AtomicScopeModel {
70 public:
71   virtual ~AtomicScopeModel() {}
72   /// Maps language specific synch scope values to internal
73   /// SyncScope enum.
74   virtual SyncScope map(unsigned S) const = 0;
75
76   /// Check if the compile-time constant synch scope value
77   /// is valid.
78   virtual bool isValid(unsigned S) const = 0;
79
80   /// Get all possible synch scope values that might be
81   /// encountered at runtime for the current language.
82   virtual ArrayRef<unsigned> getRuntimeValues() const = 0;
83
84   /// If atomic builtin function is called with invalid
85   /// synch scope value at runtime, it will fall back to a valid
86   /// synch scope value returned by this function.
87   virtual unsigned getFallBackValue() const = 0;
88
89   /// Create an atomic scope model by AtomicScopeModelKind.
90   /// \return an empty std::unique_ptr for AtomicScopeModelKind::None.
91   static std::unique_ptr<AtomicScopeModel> create(AtomicScopeModelKind K);
92 };
93
94 /// Defines the synch scope model for OpenCL.
95 class AtomicScopeOpenCLModel : public AtomicScopeModel {
96 public:
97   /// The enum values match the pre-defined macros
98   /// __OPENCL_MEMORY_SCOPE_*, which are used to define memory_scope_*
99   /// enums in opencl-c.h.
100   enum ID {
101     WorkGroup = 1,
102     Device = 2,
103     AllSVMDevices = 3,
104     SubGroup = 4,
105     Last = SubGroup
106   };
107
108   AtomicScopeOpenCLModel() {}
109
110   SyncScope map(unsigned S) const override {
111     switch (static_cast<ID>(S)) {
112     case WorkGroup:
113       return SyncScope::OpenCLWorkGroup;
114     case Device:
115       return SyncScope::OpenCLDevice;
116     case AllSVMDevices:
117       return SyncScope::OpenCLAllSVMDevices;
118     case SubGroup:
119       return SyncScope::OpenCLSubGroup;
120     }
121     llvm_unreachable("Invalid language synch scope value");
122   }
123
124   bool isValid(unsigned S) const override {
125     return S >= static_cast<unsigned>(WorkGroup) &&
126            S <= static_cast<unsigned>(Last);
127   }
128
129   ArrayRef<unsigned> getRuntimeValues() const override {
130     static_assert(Last == SubGroup, "Does not include all synch scopes");
131     static const unsigned Scopes[] = {
132         static_cast<unsigned>(WorkGroup), static_cast<unsigned>(Device),
133         static_cast<unsigned>(AllSVMDevices), static_cast<unsigned>(SubGroup)};
134     return llvm::makeArrayRef(Scopes);
135   }
136
137   unsigned getFallBackValue() const override {
138     return static_cast<unsigned>(AllSVMDevices);
139   }
140 };
141
142 inline std::unique_ptr<AtomicScopeModel>
143 AtomicScopeModel::create(AtomicScopeModelKind K) {
144   switch (K) {
145   case AtomicScopeModelKind::None:
146     return std::unique_ptr<AtomicScopeModel>{};
147   case AtomicScopeModelKind::OpenCL:
148     return llvm::make_unique<AtomicScopeOpenCLModel>();
149   }
150   llvm_unreachable("Invalid atomic scope model kind");
151 }
152 }
153
154 #endif