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 "std::nullopt" if \p SSID is not 50*0b57cec5SDimitry Andric /// supported by the AMDGPU target. 51*0b57cec5SDimitry Andric std::optional<uint8_t> getSyncScopeInclusionOrdering(SyncScope::ID SSID)52*0b57cec5SDimitry Andric getSyncScopeInclusionOrdering(SyncScope::ID SSID) const { 53*0b57cec5SDimitry Andric if (SSID == SyncScope::SingleThread || 54*0b57cec5SDimitry Andric SSID == getSingleThreadOneAddressSpaceSSID()) 55*0b57cec5SDimitry Andric return 0; 56*0b57cec5SDimitry Andric else if (SSID == getWavefrontSSID() || 57*0b57cec5SDimitry Andric SSID == getWavefrontOneAddressSpaceSSID()) 58*0b57cec5SDimitry Andric return 1; 59*0b57cec5SDimitry Andric else if (SSID == getWorkgroupSSID() || 60*0b57cec5SDimitry Andric SSID == getWorkgroupOneAddressSpaceSSID()) 61*0b57cec5SDimitry Andric return 2; 62*0b57cec5SDimitry Andric else if (SSID == getAgentSSID() || 63*0b57cec5SDimitry Andric SSID == getAgentOneAddressSpaceSSID()) 64*0b57cec5SDimitry Andric return 3; 65*0b57cec5SDimitry Andric else if (SSID == SyncScope::System || 66*0b57cec5SDimitry Andric SSID == getSystemOneAddressSpaceSSID()) 67*0b57cec5SDimitry Andric return 4; 68*0b57cec5SDimitry Andric 69*0b57cec5SDimitry Andric return std::nullopt; 70*0b57cec5SDimitry Andric } 71*0b57cec5SDimitry Andric 72*0b57cec5SDimitry Andric /// \returns True if \p SSID is restricted to single address space, false 73*0b57cec5SDimitry Andric /// otherwise isOneAddressSpace(SyncScope::ID SSID)74*0b57cec5SDimitry Andric bool isOneAddressSpace(SyncScope::ID SSID) const { 75*0b57cec5SDimitry Andric return SSID == getSingleThreadOneAddressSpaceSSID() || 76*0b57cec5SDimitry Andric SSID == getWavefrontOneAddressSpaceSSID() || 77*0b57cec5SDimitry Andric SSID == getWorkgroupOneAddressSpaceSSID() || 78*0b57cec5SDimitry Andric SSID == getAgentOneAddressSpaceSSID() || 79*0b57cec5SDimitry Andric SSID == getSystemOneAddressSpaceSSID(); 80*0b57cec5SDimitry Andric } 81*0b57cec5SDimitry Andric 82*0b57cec5SDimitry Andric public: 83*0b57cec5SDimitry Andric AMDGPUMachineModuleInfo(const MachineModuleInfo &MMI); 84*0b57cec5SDimitry Andric 85*0b57cec5SDimitry Andric /// \returns Agent synchronization scope ID (cross address space). getAgentSSID()86*0b57cec5SDimitry Andric SyncScope::ID getAgentSSID() const { 87*0b57cec5SDimitry Andric return AgentSSID; 88*0b57cec5SDimitry Andric } 89*0b57cec5SDimitry Andric /// \returns Workgroup synchronization scope ID (cross address space). getWorkgroupSSID()90*0b57cec5SDimitry Andric SyncScope::ID getWorkgroupSSID() const { 91*0b57cec5SDimitry Andric return WorkgroupSSID; 92*0b57cec5SDimitry Andric } 93*0b57cec5SDimitry Andric /// \returns Wavefront synchronization scope ID (cross address space). getWavefrontSSID()94*0b57cec5SDimitry Andric SyncScope::ID getWavefrontSSID() const { 95*0b57cec5SDimitry Andric return WavefrontSSID; 96*0b57cec5SDimitry Andric } 97*0b57cec5SDimitry Andric /// \returns System synchronization scope ID (single address space). getSystemOneAddressSpaceSSID()98*0b57cec5SDimitry Andric SyncScope::ID getSystemOneAddressSpaceSSID() const { 99*0b57cec5SDimitry Andric return SystemOneAddressSpaceSSID; 100*0b57cec5SDimitry Andric } 101*0b57cec5SDimitry Andric /// \returns Agent synchronization scope ID (single address space). getAgentOneAddressSpaceSSID()102*0b57cec5SDimitry Andric SyncScope::ID getAgentOneAddressSpaceSSID() const { 103*0b57cec5SDimitry Andric return AgentOneAddressSpaceSSID; 104*0b57cec5SDimitry Andric } 105*0b57cec5SDimitry Andric /// \returns Workgroup synchronization scope ID (single address space). getWorkgroupOneAddressSpaceSSID()106*0b57cec5SDimitry Andric SyncScope::ID getWorkgroupOneAddressSpaceSSID() const { 107*0b57cec5SDimitry Andric return WorkgroupOneAddressSpaceSSID; 108*0b57cec5SDimitry Andric } 109*0b57cec5SDimitry Andric /// \returns Wavefront synchronization scope ID (single address space). getWavefrontOneAddressSpaceSSID()110*0b57cec5SDimitry Andric SyncScope::ID getWavefrontOneAddressSpaceSSID() const { 111*0b57cec5SDimitry Andric return WavefrontOneAddressSpaceSSID; 112*0b57cec5SDimitry Andric } 113*0b57cec5SDimitry Andric /// \returns Single thread synchronization scope ID (single address space). getSingleThreadOneAddressSpaceSSID()114*0b57cec5SDimitry Andric SyncScope::ID getSingleThreadOneAddressSpaceSSID() const { 115*0b57cec5SDimitry Andric return SingleThreadOneAddressSpaceSSID; 116*0b57cec5SDimitry Andric } 117*0b57cec5SDimitry Andric 118*0b57cec5SDimitry Andric /// In AMDGPU target synchronization scopes are inclusive, meaning a 119*0b57cec5SDimitry Andric /// larger synchronization scope is inclusive of a smaller synchronization 120*0b57cec5SDimitry Andric /// scope. 121*0b57cec5SDimitry Andric /// 122*0b57cec5SDimitry Andric /// \returns True if synchronization scope \p A is larger than or equal to 123*0b57cec5SDimitry Andric /// synchronization scope \p B, false if synchronization scope \p A is smaller 124*0b57cec5SDimitry Andric /// than synchronization scope \p B, or "std::nullopt" if either 125*0b57cec5SDimitry Andric /// synchronization scope \p A or \p B is not supported by the AMDGPU target. isSyncScopeInclusion(SyncScope::ID A,SyncScope::ID B)126*0b57cec5SDimitry Andric std::optional<bool> isSyncScopeInclusion(SyncScope::ID A, 127*0b57cec5SDimitry Andric SyncScope::ID B) const { 128*0b57cec5SDimitry Andric const auto &AIO = getSyncScopeInclusionOrdering(A); 129*0b57cec5SDimitry Andric const auto &BIO = getSyncScopeInclusionOrdering(B); 130*0b57cec5SDimitry Andric if (!AIO || !BIO) 131*0b57cec5SDimitry Andric return std::nullopt; 132*0b57cec5SDimitry Andric 133*0b57cec5SDimitry Andric bool IsAOneAddressSpace = isOneAddressSpace(A); 134*0b57cec5SDimitry Andric bool IsBOneAddressSpace = isOneAddressSpace(B); 135*0b57cec5SDimitry Andric 136*0b57cec5SDimitry Andric return *AIO >= *BIO && 137*0b57cec5SDimitry Andric (IsAOneAddressSpace == IsBOneAddressSpace || !IsAOneAddressSpace); 138*0b57cec5SDimitry Andric } 139*0b57cec5SDimitry Andric }; 140*0b57cec5SDimitry Andric 141*0b57cec5SDimitry Andric } // end namespace llvm 142*0b57cec5SDimitry Andric 143*0b57cec5SDimitry Andric #endif // LLVM_LIB_TARGET_AMDGPU_AMDGPUMACHINEMODULEINFO_H 144*0b57cec5SDimitry Andric