xref: /freebsd/contrib/llvm-project/llvm/lib/Target/AMDGPU/AMDGPUMachineModuleInfo.h (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
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>
getSyncScopeInclusionOrdering(SyncScope::ID SSID)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
isOneAddressSpace(SyncScope::ID SSID)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).
getAgentSSID()87   SyncScope::ID getAgentSSID() const {
88     return AgentSSID;
89   }
90   /// \returns Workgroup synchronization scope ID (cross address space).
getWorkgroupSSID()91   SyncScope::ID getWorkgroupSSID() const {
92     return WorkgroupSSID;
93   }
94   /// \returns Wavefront synchronization scope ID (cross address space).
getWavefrontSSID()95   SyncScope::ID getWavefrontSSID() const {
96     return WavefrontSSID;
97   }
98   /// \returns System synchronization scope ID (single address space).
getSystemOneAddressSpaceSSID()99   SyncScope::ID getSystemOneAddressSpaceSSID() const {
100     return SystemOneAddressSpaceSSID;
101   }
102   /// \returns Agent synchronization scope ID (single address space).
getAgentOneAddressSpaceSSID()103   SyncScope::ID getAgentOneAddressSpaceSSID() const {
104     return AgentOneAddressSpaceSSID;
105   }
106   /// \returns Workgroup synchronization scope ID (single address space).
getWorkgroupOneAddressSpaceSSID()107   SyncScope::ID getWorkgroupOneAddressSpaceSSID() const {
108     return WorkgroupOneAddressSpaceSSID;
109   }
110   /// \returns Wavefront synchronization scope ID (single address space).
getWavefrontOneAddressSpaceSSID()111   SyncScope::ID getWavefrontOneAddressSpaceSSID() const {
112     return WavefrontOneAddressSpaceSSID;
113   }
114   /// \returns Single thread synchronization scope ID (single address space).
getSingleThreadOneAddressSpaceSSID()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.
isSyncScopeInclusion(SyncScope::ID A,SyncScope::ID B)127   std::optional<bool> isSyncScopeInclusion(SyncScope::ID A,
128                                            SyncScope::ID B) const {
129     const auto &AIO = getSyncScopeInclusionOrdering(A);
130     const auto &BIO = getSyncScopeInclusionOrdering(B);
131     if (!AIO || !BIO)
132       return std::nullopt;
133 
134     bool IsAOneAddressSpace = isOneAddressSpace(A);
135     bool IsBOneAddressSpace = isOneAddressSpace(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