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" 190b57cec5SDimitry Andric 200b57cec5SDimitry Andric namespace llvm { 210b57cec5SDimitry Andric 220b57cec5SDimitry Andric class AMDGPUMachineModuleInfo final : public MachineModuleInfoELF { 230b57cec5SDimitry Andric private: 240b57cec5SDimitry Andric 250b57cec5SDimitry Andric // All supported memory/synchronization scopes can be found here: 260b57cec5SDimitry Andric // http://llvm.org/docs/AMDGPUUsage.html#memory-scopes 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric /// Agent synchronization scope ID (cross address space). 290b57cec5SDimitry Andric SyncScope::ID AgentSSID; 300b57cec5SDimitry Andric /// Workgroup synchronization scope ID (cross address space). 310b57cec5SDimitry Andric SyncScope::ID WorkgroupSSID; 320b57cec5SDimitry Andric /// Wavefront synchronization scope ID (cross address space). 330b57cec5SDimitry Andric SyncScope::ID WavefrontSSID; 340b57cec5SDimitry Andric /// System synchronization scope ID (single address space). 350b57cec5SDimitry Andric SyncScope::ID SystemOneAddressSpaceSSID; 360b57cec5SDimitry Andric /// Agent synchronization scope ID (single address space). 370b57cec5SDimitry Andric SyncScope::ID AgentOneAddressSpaceSSID; 380b57cec5SDimitry Andric /// Workgroup synchronization scope ID (single address space). 390b57cec5SDimitry Andric SyncScope::ID WorkgroupOneAddressSpaceSSID; 400b57cec5SDimitry Andric /// Wavefront synchronization scope ID (single address space). 410b57cec5SDimitry Andric SyncScope::ID WavefrontOneAddressSpaceSSID; 420b57cec5SDimitry Andric /// Single thread synchronization scope ID (single address space). 430b57cec5SDimitry Andric SyncScope::ID SingleThreadOneAddressSpaceSSID; 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric /// In AMDGPU target synchronization scopes are inclusive, meaning a 460b57cec5SDimitry Andric /// larger synchronization scope is inclusive of a smaller synchronization 470b57cec5SDimitry Andric /// scope. 480b57cec5SDimitry Andric /// 49bdd1243dSDimitry Andric /// \returns \p SSID's inclusion ordering, or "std::nullopt" if \p SSID is not 500b57cec5SDimitry Andric /// supported by the AMDGPU target. 51bdd1243dSDimitry Andric std::optional<uint8_t> getSyncScopeInclusionOrdering(SyncScope::ID SSID)52bdd1243dSDimitry Andric getSyncScopeInclusionOrdering(SyncScope::ID SSID) const { 530b57cec5SDimitry Andric if (SSID == SyncScope::SingleThread || 540b57cec5SDimitry Andric SSID == getSingleThreadOneAddressSpaceSSID()) 550b57cec5SDimitry Andric return 0; 560b57cec5SDimitry Andric else if (SSID == getWavefrontSSID() || 570b57cec5SDimitry Andric SSID == getWavefrontOneAddressSpaceSSID()) 580b57cec5SDimitry Andric return 1; 590b57cec5SDimitry Andric else if (SSID == getWorkgroupSSID() || 600b57cec5SDimitry Andric SSID == getWorkgroupOneAddressSpaceSSID()) 610b57cec5SDimitry Andric return 2; 620b57cec5SDimitry Andric else if (SSID == getAgentSSID() || 630b57cec5SDimitry Andric SSID == getAgentOneAddressSpaceSSID()) 640b57cec5SDimitry Andric return 3; 650b57cec5SDimitry Andric else if (SSID == SyncScope::System || 660b57cec5SDimitry Andric SSID == getSystemOneAddressSpaceSSID()) 670b57cec5SDimitry Andric return 4; 680b57cec5SDimitry Andric 69bdd1243dSDimitry Andric return std::nullopt; 700b57cec5SDimitry Andric } 710b57cec5SDimitry Andric 720b57cec5SDimitry Andric /// \returns True if \p SSID is restricted to single address space, false 730b57cec5SDimitry Andric /// otherwise isOneAddressSpace(SyncScope::ID SSID)740b57cec5SDimitry Andric bool isOneAddressSpace(SyncScope::ID SSID) const { 750b57cec5SDimitry Andric return SSID == getSingleThreadOneAddressSpaceSSID() || 760b57cec5SDimitry Andric SSID == getWavefrontOneAddressSpaceSSID() || 770b57cec5SDimitry Andric SSID == getWorkgroupOneAddressSpaceSSID() || 780b57cec5SDimitry Andric SSID == getAgentOneAddressSpaceSSID() || 790b57cec5SDimitry Andric SSID == getSystemOneAddressSpaceSSID(); 800b57cec5SDimitry Andric } 810b57cec5SDimitry Andric 820b57cec5SDimitry Andric public: 830b57cec5SDimitry Andric AMDGPUMachineModuleInfo(const MachineModuleInfo &MMI); 840b57cec5SDimitry Andric 850b57cec5SDimitry Andric /// \returns Agent synchronization scope ID (cross address space). getAgentSSID()860b57cec5SDimitry Andric SyncScope::ID getAgentSSID() const { 870b57cec5SDimitry Andric return AgentSSID; 880b57cec5SDimitry Andric } 890b57cec5SDimitry Andric /// \returns Workgroup synchronization scope ID (cross address space). getWorkgroupSSID()900b57cec5SDimitry Andric SyncScope::ID getWorkgroupSSID() const { 910b57cec5SDimitry Andric return WorkgroupSSID; 920b57cec5SDimitry Andric } 930b57cec5SDimitry Andric /// \returns Wavefront synchronization scope ID (cross address space). getWavefrontSSID()940b57cec5SDimitry Andric SyncScope::ID getWavefrontSSID() const { 950b57cec5SDimitry Andric return WavefrontSSID; 960b57cec5SDimitry Andric } 970b57cec5SDimitry Andric /// \returns System synchronization scope ID (single address space). getSystemOneAddressSpaceSSID()980b57cec5SDimitry Andric SyncScope::ID getSystemOneAddressSpaceSSID() const { 990b57cec5SDimitry Andric return SystemOneAddressSpaceSSID; 1000b57cec5SDimitry Andric } 1010b57cec5SDimitry Andric /// \returns Agent synchronization scope ID (single address space). getAgentOneAddressSpaceSSID()1020b57cec5SDimitry Andric SyncScope::ID getAgentOneAddressSpaceSSID() const { 1030b57cec5SDimitry Andric return AgentOneAddressSpaceSSID; 1040b57cec5SDimitry Andric } 1050b57cec5SDimitry Andric /// \returns Workgroup synchronization scope ID (single address space). getWorkgroupOneAddressSpaceSSID()1060b57cec5SDimitry Andric SyncScope::ID getWorkgroupOneAddressSpaceSSID() const { 1070b57cec5SDimitry Andric return WorkgroupOneAddressSpaceSSID; 1080b57cec5SDimitry Andric } 1090b57cec5SDimitry Andric /// \returns Wavefront synchronization scope ID (single address space). getWavefrontOneAddressSpaceSSID()1100b57cec5SDimitry Andric SyncScope::ID getWavefrontOneAddressSpaceSSID() const { 1110b57cec5SDimitry Andric return WavefrontOneAddressSpaceSSID; 1120b57cec5SDimitry Andric } 1130b57cec5SDimitry Andric /// \returns Single thread synchronization scope ID (single address space). getSingleThreadOneAddressSpaceSSID()1140b57cec5SDimitry Andric SyncScope::ID getSingleThreadOneAddressSpaceSSID() const { 1150b57cec5SDimitry Andric return SingleThreadOneAddressSpaceSSID; 1160b57cec5SDimitry Andric } 1170b57cec5SDimitry Andric 1180b57cec5SDimitry Andric /// In AMDGPU target synchronization scopes are inclusive, meaning a 1190b57cec5SDimitry Andric /// larger synchronization scope is inclusive of a smaller synchronization 1200b57cec5SDimitry Andric /// scope. 1210b57cec5SDimitry Andric /// 1220b57cec5SDimitry Andric /// \returns True if synchronization scope \p A is larger than or equal to 1230b57cec5SDimitry Andric /// synchronization scope \p B, false if synchronization scope \p A is smaller 124bdd1243dSDimitry Andric /// than synchronization scope \p B, or "std::nullopt" if either 125bdd1243dSDimitry Andric /// synchronization scope \p A or \p B is not supported by the AMDGPU target. isSyncScopeInclusion(SyncScope::ID A,SyncScope::ID B)126bdd1243dSDimitry Andric std::optional<bool> isSyncScopeInclusion(SyncScope::ID A, 127bdd1243dSDimitry Andric SyncScope::ID B) const { 1280b57cec5SDimitry Andric const auto &AIO = getSyncScopeInclusionOrdering(A); 1290b57cec5SDimitry Andric const auto &BIO = getSyncScopeInclusionOrdering(B); 1300b57cec5SDimitry Andric if (!AIO || !BIO) 131bdd1243dSDimitry Andric return std::nullopt; 1320b57cec5SDimitry Andric 1330b57cec5SDimitry Andric bool IsAOneAddressSpace = isOneAddressSpace(A); 1340b57cec5SDimitry Andric bool IsBOneAddressSpace = isOneAddressSpace(B); 1350b57cec5SDimitry Andric 136bdd1243dSDimitry Andric return *AIO >= *BIO && 1370b57cec5SDimitry Andric (IsAOneAddressSpace == IsBOneAddressSpace || !IsAOneAddressSpace); 1380b57cec5SDimitry Andric } 1390b57cec5SDimitry Andric }; 1400b57cec5SDimitry Andric 1410b57cec5SDimitry Andric } // end namespace llvm 1420b57cec5SDimitry Andric 1430b57cec5SDimitry Andric #endif // LLVM_LIB_TARGET_AMDGPU_AMDGPUMACHINEMODULEINFO_H 144