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