Warning: That file was not part of the compilation database. It may have many parsing errors.
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 |
155 |
Warning: That file was not part of the compilation database. It may have many parsing errors.