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