1 | //===--- AMDGPUMachineModuleInfo.h ------------------------------*- 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-exception |
6 | // |
7 | //===----------------------------------------------------------------------===// |
8 | // |
9 | /// \file |
10 | /// AMDGPU Machine Module Info. |
11 | /// |
12 | // |
13 | //===----------------------------------------------------------------------===// |
14 | |
15 | #ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUMACHINEMODULEINFO_H |
16 | #define LLVM_LIB_TARGET_AMDGPU_AMDGPUMACHINEMODULEINFO_H |
17 | |
18 | #include "llvm/CodeGen/MachineModuleInfoImpls.h" |
19 | #include "llvm/IR/LLVMContext.h" |
20 | |
21 | namespace llvm { |
22 | |
23 | class AMDGPUMachineModuleInfo final : public MachineModuleInfoELF { |
24 | private: |
25 | |
26 | // All supported memory/synchronization scopes can be found here: |
27 | // http://llvm.org/docs/AMDGPUUsage.html#memory-scopes |
28 | |
29 | /// Agent synchronization scope ID (cross address space). |
30 | SyncScope::ID AgentSSID; |
31 | /// Workgroup synchronization scope ID (cross address space). |
32 | SyncScope::ID WorkgroupSSID; |
33 | /// Wavefront synchronization scope ID (cross address space). |
34 | SyncScope::ID WavefrontSSID; |
35 | /// System synchronization scope ID (single address space). |
36 | SyncScope::ID SystemOneAddressSpaceSSID; |
37 | /// Agent synchronization scope ID (single address space). |
38 | SyncScope::ID AgentOneAddressSpaceSSID; |
39 | /// Workgroup synchronization scope ID (single address space). |
40 | SyncScope::ID WorkgroupOneAddressSpaceSSID; |
41 | /// Wavefront synchronization scope ID (single address space). |
42 | SyncScope::ID WavefrontOneAddressSpaceSSID; |
43 | /// Single thread synchronization scope ID (single address space). |
44 | SyncScope::ID SingleThreadOneAddressSpaceSSID; |
45 | |
46 | /// In AMDGPU target synchronization scopes are inclusive, meaning a |
47 | /// larger synchronization scope is inclusive of a smaller synchronization |
48 | /// scope. |
49 | /// |
50 | /// \returns \p SSID's inclusion ordering, or "std::nullopt" if \p SSID is not |
51 | /// supported by the AMDGPU target. |
52 | std::optional<uint8_t> |
53 | getSyncScopeInclusionOrdering(SyncScope::ID SSID) const { |
54 | if (SSID == SyncScope::SingleThread || |
55 | SSID == getSingleThreadOneAddressSpaceSSID()) |
56 | return 0; |
57 | else if (SSID == getWavefrontSSID() || |
58 | SSID == getWavefrontOneAddressSpaceSSID()) |
59 | return 1; |
60 | else if (SSID == getWorkgroupSSID() || |
61 | SSID == getWorkgroupOneAddressSpaceSSID()) |
62 | return 2; |
63 | else if (SSID == getAgentSSID() || |
64 | SSID == getAgentOneAddressSpaceSSID()) |
65 | return 3; |
66 | else if (SSID == SyncScope::System || |
67 | SSID == getSystemOneAddressSpaceSSID()) |
68 | return 4; |
69 | |
70 | return std::nullopt; |
71 | } |
72 | |
73 | /// \returns True if \p SSID is restricted to single address space, false |
74 | /// otherwise |
75 | bool isOneAddressSpace(SyncScope::ID SSID) const { |
76 | return SSID == getSingleThreadOneAddressSpaceSSID() || |
77 | SSID == getWavefrontOneAddressSpaceSSID() || |
78 | SSID == getWorkgroupOneAddressSpaceSSID() || |
79 | SSID == getAgentOneAddressSpaceSSID() || |
80 | SSID == getSystemOneAddressSpaceSSID(); |
81 | } |
82 | |
83 | public: |
84 | AMDGPUMachineModuleInfo(const MachineModuleInfo &MMI); |
85 | |
86 | /// \returns Agent synchronization scope ID (cross address space). |
87 | SyncScope::ID getAgentSSID() const { |
88 | return AgentSSID; |
89 | } |
90 | /// \returns Workgroup synchronization scope ID (cross address space). |
91 | SyncScope::ID getWorkgroupSSID() const { |
92 | return WorkgroupSSID; |
93 | } |
94 | /// \returns Wavefront synchronization scope ID (cross address space). |
95 | SyncScope::ID getWavefrontSSID() const { |
96 | return WavefrontSSID; |
97 | } |
98 | /// \returns System synchronization scope ID (single address space). |
99 | SyncScope::ID getSystemOneAddressSpaceSSID() const { |
100 | return SystemOneAddressSpaceSSID; |
101 | } |
102 | /// \returns Agent synchronization scope ID (single address space). |
103 | SyncScope::ID getAgentOneAddressSpaceSSID() const { |
104 | return AgentOneAddressSpaceSSID; |
105 | } |
106 | /// \returns Workgroup synchronization scope ID (single address space). |
107 | SyncScope::ID getWorkgroupOneAddressSpaceSSID() const { |
108 | return WorkgroupOneAddressSpaceSSID; |
109 | } |
110 | /// \returns Wavefront synchronization scope ID (single address space). |
111 | SyncScope::ID getWavefrontOneAddressSpaceSSID() const { |
112 | return WavefrontOneAddressSpaceSSID; |
113 | } |
114 | /// \returns Single thread synchronization scope ID (single address space). |
115 | SyncScope::ID getSingleThreadOneAddressSpaceSSID() const { |
116 | return SingleThreadOneAddressSpaceSSID; |
117 | } |
118 | |
119 | /// In AMDGPU target synchronization scopes are inclusive, meaning a |
120 | /// larger synchronization scope is inclusive of a smaller synchronization |
121 | /// scope. |
122 | /// |
123 | /// \returns True if synchronization scope \p A is larger than or equal to |
124 | /// synchronization scope \p B, false if synchronization scope \p A is smaller |
125 | /// than synchronization scope \p B, or "std::nullopt" if either |
126 | /// synchronization scope \p A or \p B is not supported by the AMDGPU target. |
127 | std::optional<bool> isSyncScopeInclusion(SyncScope::ID A, |
128 | SyncScope::ID B) const { |
129 | const auto &AIO = getSyncScopeInclusionOrdering(SSID: A); |
130 | const auto &BIO = getSyncScopeInclusionOrdering(SSID: B); |
131 | if (!AIO || !BIO) |
132 | return std::nullopt; |
133 | |
134 | bool IsAOneAddressSpace = isOneAddressSpace(SSID: A); |
135 | bool IsBOneAddressSpace = isOneAddressSpace(SSID: B); |
136 | |
137 | return *AIO >= *BIO && |
138 | (IsAOneAddressSpace == IsBOneAddressSpace || !IsAOneAddressSpace); |
139 | } |
140 | }; |
141 | |
142 | } // end namespace llvm |
143 | |
144 | #endif // LLVM_LIB_TARGET_AMDGPU_AMDGPUMACHINEMODULEINFO_H |
145 | |