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