|  | //===--- AMDGPUMachineModuleInfo.h ------------------------------*- C++ -*-===// | 
|  | // | 
|  | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | 
|  | // See https://llvm.org/LICENSE.txt for license information. | 
|  | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  | // | 
|  | /// \file | 
|  | /// AMDGPU Machine Module Info. | 
|  | /// | 
|  | // | 
|  | //===----------------------------------------------------------------------===// | 
|  |  | 
|  | #ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUMACHINEMODULEINFO_H | 
|  | #define LLVM_LIB_TARGET_AMDGPU_AMDGPUMACHINEMODULEINFO_H | 
|  |  | 
|  | #include "llvm/ADT/None.h" | 
|  | #include "llvm/ADT/Optional.h" | 
|  | #include "llvm/CodeGen/MachineModuleInfo.h" | 
|  | #include "llvm/CodeGen/MachineModuleInfoImpls.h" | 
|  | #include "llvm/IR/LLVMContext.h" | 
|  |  | 
|  | namespace llvm { | 
|  |  | 
|  | class AMDGPUMachineModuleInfo final : public MachineModuleInfoELF { | 
|  | private: | 
|  |  | 
|  | // All supported memory/synchronization scopes can be found here: | 
|  | //   http://llvm.org/docs/AMDGPUUsage.html#memory-scopes | 
|  |  | 
|  | /// Agent synchronization scope ID (cross address space). | 
|  | SyncScope::ID AgentSSID; | 
|  | /// Workgroup synchronization scope ID (cross address space). | 
|  | SyncScope::ID WorkgroupSSID; | 
|  | /// Wavefront synchronization scope ID (cross address space). | 
|  | SyncScope::ID WavefrontSSID; | 
|  | /// System synchronization scope ID (single address space). | 
|  | SyncScope::ID SystemOneAddressSpaceSSID; | 
|  | /// Agent synchronization scope ID (single address space). | 
|  | SyncScope::ID AgentOneAddressSpaceSSID; | 
|  | /// Workgroup synchronization scope ID (single address space). | 
|  | SyncScope::ID WorkgroupOneAddressSpaceSSID; | 
|  | /// Wavefront synchronization scope ID (single address space). | 
|  | SyncScope::ID WavefrontOneAddressSpaceSSID; | 
|  | /// Single thread synchronization scope ID (single address space). | 
|  | SyncScope::ID SingleThreadOneAddressSpaceSSID; | 
|  |  | 
|  | /// In AMDGPU target synchronization scopes are inclusive, meaning a | 
|  | /// larger synchronization scope is inclusive of a smaller synchronization | 
|  | /// scope. | 
|  | /// | 
|  | /// \returns \p SSID's inclusion ordering, or "None" if \p SSID is not | 
|  | /// supported by the AMDGPU target. | 
|  | Optional<uint8_t> getSyncScopeInclusionOrdering(SyncScope::ID SSID) const { | 
|  | if (SSID == SyncScope::SingleThread || | 
|  | SSID == getSingleThreadOneAddressSpaceSSID()) | 
|  | return 0; | 
|  | else if (SSID == getWavefrontSSID() || | 
|  | SSID == getWavefrontOneAddressSpaceSSID()) | 
|  | return 1; | 
|  | else if (SSID == getWorkgroupSSID() || | 
|  | SSID == getWorkgroupOneAddressSpaceSSID()) | 
|  | return 2; | 
|  | else if (SSID == getAgentSSID() || | 
|  | SSID == getAgentOneAddressSpaceSSID()) | 
|  | return 3; | 
|  | else if (SSID == SyncScope::System || | 
|  | SSID == getSystemOneAddressSpaceSSID()) | 
|  | return 4; | 
|  |  | 
|  | return None; | 
|  | } | 
|  |  | 
|  | /// \returns True if \p SSID is restricted to single address space, false | 
|  | /// otherwise | 
|  | bool isOneAddressSpace(SyncScope::ID SSID) const { | 
|  | return SSID == getSingleThreadOneAddressSpaceSSID() || | 
|  | SSID == getWavefrontOneAddressSpaceSSID() || | 
|  | SSID == getWorkgroupOneAddressSpaceSSID() || | 
|  | SSID == getAgentOneAddressSpaceSSID() || | 
|  | SSID == getSystemOneAddressSpaceSSID(); | 
|  | } | 
|  |  | 
|  | public: | 
|  | AMDGPUMachineModuleInfo(const MachineModuleInfo &MMI); | 
|  |  | 
|  | /// \returns Agent synchronization scope ID (cross address space). | 
|  | SyncScope::ID getAgentSSID() const { | 
|  | return AgentSSID; | 
|  | } | 
|  | /// \returns Workgroup synchronization scope ID (cross address space). | 
|  | SyncScope::ID getWorkgroupSSID() const { | 
|  | return WorkgroupSSID; | 
|  | } | 
|  | /// \returns Wavefront synchronization scope ID (cross address space). | 
|  | SyncScope::ID getWavefrontSSID() const { | 
|  | return WavefrontSSID; | 
|  | } | 
|  | /// \returns System synchronization scope ID (single address space). | 
|  | SyncScope::ID getSystemOneAddressSpaceSSID() const { | 
|  | return SystemOneAddressSpaceSSID; | 
|  | } | 
|  | /// \returns Agent synchronization scope ID (single address space). | 
|  | SyncScope::ID getAgentOneAddressSpaceSSID() const { | 
|  | return AgentOneAddressSpaceSSID; | 
|  | } | 
|  | /// \returns Workgroup synchronization scope ID (single address space). | 
|  | SyncScope::ID getWorkgroupOneAddressSpaceSSID() const { | 
|  | return WorkgroupOneAddressSpaceSSID; | 
|  | } | 
|  | /// \returns Wavefront synchronization scope ID (single address space). | 
|  | SyncScope::ID getWavefrontOneAddressSpaceSSID() const { | 
|  | return WavefrontOneAddressSpaceSSID; | 
|  | } | 
|  | /// \returns Single thread synchronization scope ID (single address space). | 
|  | SyncScope::ID getSingleThreadOneAddressSpaceSSID() const { | 
|  | return SingleThreadOneAddressSpaceSSID; | 
|  | } | 
|  |  | 
|  | /// In AMDGPU target synchronization scopes are inclusive, meaning a | 
|  | /// larger synchronization scope is inclusive of a smaller synchronization | 
|  | /// scope. | 
|  | /// | 
|  | /// \returns True if synchronization scope \p A is larger than or equal to | 
|  | /// synchronization scope \p B, false if synchronization scope \p A is smaller | 
|  | /// than synchronization scope \p B, or "None" if either synchronization scope | 
|  | /// \p A or \p B is not supported by the AMDGPU target. | 
|  | Optional<bool> isSyncScopeInclusion(SyncScope::ID A, SyncScope::ID B) const { | 
|  | const auto &AIO = getSyncScopeInclusionOrdering(A); | 
|  | const auto &BIO = getSyncScopeInclusionOrdering(B); | 
|  | if (!AIO || !BIO) | 
|  | return None; | 
|  |  | 
|  | bool IsAOneAddressSpace = isOneAddressSpace(A); | 
|  | bool IsBOneAddressSpace = isOneAddressSpace(B); | 
|  |  | 
|  | return AIO.getValue() >= BIO.getValue() && | 
|  | (IsAOneAddressSpace == IsBOneAddressSpace || !IsAOneAddressSpace); | 
|  | } | 
|  | }; | 
|  |  | 
|  | } // end namespace llvm | 
|  |  | 
|  | #endif // LLVM_LIB_TARGET_AMDGPU_AMDGPUMACHINEMODULEINFO_H |