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