10b57cec5SDimitry Andric //===--- AMDGPUMachineModuleInfo.h ------------------------------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric /// \file 100b57cec5SDimitry Andric /// AMDGPU Machine Module Info. 110b57cec5SDimitry Andric /// 120b57cec5SDimitry Andric // 130b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 140b57cec5SDimitry Andric 150b57cec5SDimitry Andric #ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUMACHINEMODULEINFO_H 160b57cec5SDimitry Andric #define LLVM_LIB_TARGET_AMDGPU_AMDGPUMACHINEMODULEINFO_H 170b57cec5SDimitry Andric 180b57cec5SDimitry Andric #include "llvm/CodeGen/MachineModuleInfoImpls.h" 19*0fca6ea1SDimitry Andric #include "llvm/IR/LLVMContext.h" 200b57cec5SDimitry Andric 210b57cec5SDimitry Andric namespace llvm { 220b57cec5SDimitry Andric 230b57cec5SDimitry Andric class AMDGPUMachineModuleInfo final : public MachineModuleInfoELF { 240b57cec5SDimitry Andric private: 250b57cec5SDimitry Andric 260b57cec5SDimitry Andric // All supported memory/synchronization scopes can be found here: 270b57cec5SDimitry Andric // http://llvm.org/docs/AMDGPUUsage.html#memory-scopes 280b57cec5SDimitry Andric 290b57cec5SDimitry Andric /// Agent synchronization scope ID (cross address space). 300b57cec5SDimitry Andric SyncScope::ID AgentSSID; 310b57cec5SDimitry Andric /// Workgroup synchronization scope ID (cross address space). 320b57cec5SDimitry Andric SyncScope::ID WorkgroupSSID; 330b57cec5SDimitry Andric /// Wavefront synchronization scope ID (cross address space). 340b57cec5SDimitry Andric SyncScope::ID WavefrontSSID; 350b57cec5SDimitry Andric /// System synchronization scope ID (single address space). 360b57cec5SDimitry Andric SyncScope::ID SystemOneAddressSpaceSSID; 370b57cec5SDimitry Andric /// Agent synchronization scope ID (single address space). 380b57cec5SDimitry Andric SyncScope::ID AgentOneAddressSpaceSSID; 390b57cec5SDimitry Andric /// Workgroup synchronization scope ID (single address space). 400b57cec5SDimitry Andric SyncScope::ID WorkgroupOneAddressSpaceSSID; 410b57cec5SDimitry Andric /// Wavefront synchronization scope ID (single address space). 420b57cec5SDimitry Andric SyncScope::ID WavefrontOneAddressSpaceSSID; 430b57cec5SDimitry Andric /// Single thread synchronization scope ID (single address space). 440b57cec5SDimitry Andric SyncScope::ID SingleThreadOneAddressSpaceSSID; 450b57cec5SDimitry Andric 460b57cec5SDimitry Andric /// In AMDGPU target synchronization scopes are inclusive, meaning a 470b57cec5SDimitry Andric /// larger synchronization scope is inclusive of a smaller synchronization 480b57cec5SDimitry Andric /// scope. 490b57cec5SDimitry Andric /// 50bdd1243dSDimitry Andric /// \returns \p SSID's inclusion ordering, or "std::nullopt" if \p SSID is not 510b57cec5SDimitry Andric /// supported by the AMDGPU target. 52bdd1243dSDimitry Andric std::optional<uint8_t> getSyncScopeInclusionOrdering(SyncScope::ID SSID)53bdd1243dSDimitry Andric getSyncScopeInclusionOrdering(SyncScope::ID SSID) const { 540b57cec5SDimitry Andric if (SSID == SyncScope::SingleThread || 550b57cec5SDimitry Andric SSID == getSingleThreadOneAddressSpaceSSID()) 560b57cec5SDimitry Andric return 0; 570b57cec5SDimitry Andric else if (SSID == getWavefrontSSID() || 580b57cec5SDimitry Andric SSID == getWavefrontOneAddressSpaceSSID()) 590b57cec5SDimitry Andric return 1; 600b57cec5SDimitry Andric else if (SSID == getWorkgroupSSID() || 610b57cec5SDimitry Andric SSID == getWorkgroupOneAddressSpaceSSID()) 620b57cec5SDimitry Andric return 2; 630b57cec5SDimitry Andric else if (SSID == getAgentSSID() || 640b57cec5SDimitry Andric SSID == getAgentOneAddressSpaceSSID()) 650b57cec5SDimitry Andric return 3; 660b57cec5SDimitry Andric else if (SSID == SyncScope::System || 670b57cec5SDimitry Andric SSID == getSystemOneAddressSpaceSSID()) 680b57cec5SDimitry Andric return 4; 690b57cec5SDimitry Andric 70bdd1243dSDimitry Andric return std::nullopt; 710b57cec5SDimitry Andric } 720b57cec5SDimitry Andric 730b57cec5SDimitry Andric /// \returns True if \p SSID is restricted to single address space, false 740b57cec5SDimitry Andric /// otherwise isOneAddressSpace(SyncScope::ID SSID)750b57cec5SDimitry Andric bool isOneAddressSpace(SyncScope::ID SSID) const { 760b57cec5SDimitry Andric return SSID == getSingleThreadOneAddressSpaceSSID() || 770b57cec5SDimitry Andric SSID == getWavefrontOneAddressSpaceSSID() || 780b57cec5SDimitry Andric SSID == getWorkgroupOneAddressSpaceSSID() || 790b57cec5SDimitry Andric SSID == getAgentOneAddressSpaceSSID() || 800b57cec5SDimitry Andric SSID == getSystemOneAddressSpaceSSID(); 810b57cec5SDimitry Andric } 820b57cec5SDimitry Andric 830b57cec5SDimitry Andric public: 840b57cec5SDimitry Andric AMDGPUMachineModuleInfo(const MachineModuleInfo &MMI); 850b57cec5SDimitry Andric 860b57cec5SDimitry Andric /// \returns Agent synchronization scope ID (cross address space). getAgentSSID()870b57cec5SDimitry Andric SyncScope::ID getAgentSSID() const { 880b57cec5SDimitry Andric return AgentSSID; 890b57cec5SDimitry Andric } 900b57cec5SDimitry Andric /// \returns Workgroup synchronization scope ID (cross address space). getWorkgroupSSID()910b57cec5SDimitry Andric SyncScope::ID getWorkgroupSSID() const { 920b57cec5SDimitry Andric return WorkgroupSSID; 930b57cec5SDimitry Andric } 940b57cec5SDimitry Andric /// \returns Wavefront synchronization scope ID (cross address space). getWavefrontSSID()950b57cec5SDimitry Andric SyncScope::ID getWavefrontSSID() const { 960b57cec5SDimitry Andric return WavefrontSSID; 970b57cec5SDimitry Andric } 980b57cec5SDimitry Andric /// \returns System synchronization scope ID (single address space). getSystemOneAddressSpaceSSID()990b57cec5SDimitry Andric SyncScope::ID getSystemOneAddressSpaceSSID() const { 1000b57cec5SDimitry Andric return SystemOneAddressSpaceSSID; 1010b57cec5SDimitry Andric } 1020b57cec5SDimitry Andric /// \returns Agent synchronization scope ID (single address space). getAgentOneAddressSpaceSSID()1030b57cec5SDimitry Andric SyncScope::ID getAgentOneAddressSpaceSSID() const { 1040b57cec5SDimitry Andric return AgentOneAddressSpaceSSID; 1050b57cec5SDimitry Andric } 1060b57cec5SDimitry Andric /// \returns Workgroup synchronization scope ID (single address space). getWorkgroupOneAddressSpaceSSID()1070b57cec5SDimitry Andric SyncScope::ID getWorkgroupOneAddressSpaceSSID() const { 1080b57cec5SDimitry Andric return WorkgroupOneAddressSpaceSSID; 1090b57cec5SDimitry Andric } 1100b57cec5SDimitry Andric /// \returns Wavefront synchronization scope ID (single address space). getWavefrontOneAddressSpaceSSID()1110b57cec5SDimitry Andric SyncScope::ID getWavefrontOneAddressSpaceSSID() const { 1120b57cec5SDimitry Andric return WavefrontOneAddressSpaceSSID; 1130b57cec5SDimitry Andric } 1140b57cec5SDimitry Andric /// \returns Single thread synchronization scope ID (single address space). getSingleThreadOneAddressSpaceSSID()1150b57cec5SDimitry Andric SyncScope::ID getSingleThreadOneAddressSpaceSSID() const { 1160b57cec5SDimitry Andric return SingleThreadOneAddressSpaceSSID; 1170b57cec5SDimitry Andric } 1180b57cec5SDimitry Andric 1190b57cec5SDimitry Andric /// In AMDGPU target synchronization scopes are inclusive, meaning a 1200b57cec5SDimitry Andric /// larger synchronization scope is inclusive of a smaller synchronization 1210b57cec5SDimitry Andric /// scope. 1220b57cec5SDimitry Andric /// 1230b57cec5SDimitry Andric /// \returns True if synchronization scope \p A is larger than or equal to 1240b57cec5SDimitry Andric /// synchronization scope \p B, false if synchronization scope \p A is smaller 125bdd1243dSDimitry Andric /// than synchronization scope \p B, or "std::nullopt" if either 126bdd1243dSDimitry Andric /// synchronization scope \p A or \p B is not supported by the AMDGPU target. isSyncScopeInclusion(SyncScope::ID A,SyncScope::ID B)127bdd1243dSDimitry Andric std::optional<bool> isSyncScopeInclusion(SyncScope::ID A, 128bdd1243dSDimitry Andric SyncScope::ID B) const { 1290b57cec5SDimitry Andric const auto &AIO = getSyncScopeInclusionOrdering(A); 1300b57cec5SDimitry Andric const auto &BIO = getSyncScopeInclusionOrdering(B); 1310b57cec5SDimitry Andric if (!AIO || !BIO) 132bdd1243dSDimitry Andric return std::nullopt; 1330b57cec5SDimitry Andric 1340b57cec5SDimitry Andric bool IsAOneAddressSpace = isOneAddressSpace(A); 1350b57cec5SDimitry Andric bool IsBOneAddressSpace = isOneAddressSpace(B); 1360b57cec5SDimitry Andric 137bdd1243dSDimitry Andric return *AIO >= *BIO && 1380b57cec5SDimitry Andric (IsAOneAddressSpace == IsBOneAddressSpace || !IsAOneAddressSpace); 1390b57cec5SDimitry Andric } 1400b57cec5SDimitry Andric }; 1410b57cec5SDimitry Andric 1420b57cec5SDimitry Andric } // end namespace llvm 1430b57cec5SDimitry Andric 1440b57cec5SDimitry Andric #endif // LLVM_LIB_TARGET_AMDGPU_AMDGPUMACHINEMODULEINFO_H 145