1//===--- AMDGPUMachineModuleInfo.h ------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9/// \file
10/// AMDGPU Machine Module Info.
11///
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUMACHINEMODULEINFO_H
16#define LLVM_LIB_TARGET_AMDGPU_AMDGPUMACHINEMODULEINFO_H
17
18#include "llvm/ADT/None.h"
19#include "llvm/ADT/Optional.h"
20#include "llvm/CodeGen/MachineModuleInfo.h"
21#include "llvm/CodeGen/MachineModuleInfoImpls.h"
22#include "llvm/IR/LLVMContext.h"
23
24namespace llvm {
25
26class AMDGPUMachineModuleInfo final : public MachineModuleInfoELF {
27private:
28
29  // All supported memory/synchronization scopes can be found here:
30  //   http://llvm.org/docs/AMDGPUUsage.html#memory-scopes
31
32  /// Agent synchronization scope ID (cross address space).
33  SyncScope::ID AgentSSID;
34  /// Workgroup synchronization scope ID (cross address space).
35  SyncScope::ID WorkgroupSSID;
36  /// Wavefront synchronization scope ID (cross address space).
37  SyncScope::ID WavefrontSSID;
38  /// System synchronization scope ID (single address space).
39  SyncScope::ID SystemOneAddressSpaceSSID;
40  /// Agent synchronization scope ID (single address space).
41  SyncScope::ID AgentOneAddressSpaceSSID;
42  /// Workgroup synchronization scope ID (single address space).
43  SyncScope::ID WorkgroupOneAddressSpaceSSID;
44  /// Wavefront synchronization scope ID (single address space).
45  SyncScope::ID WavefrontOneAddressSpaceSSID;
46  /// Single thread synchronization scope ID (single address space).
47  SyncScope::ID SingleThreadOneAddressSpaceSSID;
48
49  /// In AMDGPU target synchronization scopes are inclusive, meaning a
50  /// larger synchronization scope is inclusive of a smaller synchronization
51  /// scope.
52  ///
53  /// \returns \p SSID's inclusion ordering, or "None" if \p SSID is not
54  /// supported by the AMDGPU target.
55  Optional<uint8_t> getSyncScopeInclusionOrdering(SyncScope::ID SSID) const {
56    if (SSID == SyncScope::SingleThread ||
57        SSID == getSingleThreadOneAddressSpaceSSID())
58      return 0;
59    else if (SSID == getWavefrontSSID() ||
60             SSID == getWavefrontOneAddressSpaceSSID())
61      return 1;
62    else if (SSID == getWorkgroupSSID() ||
63             SSID == getWorkgroupOneAddressSpaceSSID())
64      return 2;
65    else if (SSID == getAgentSSID() ||
66             SSID == getAgentOneAddressSpaceSSID())
67      return 3;
68    else if (SSID == SyncScope::System ||
69             SSID == getSystemOneAddressSpaceSSID())
70      return 4;
71
72    return None;
73  }
74
75  /// \returns True if \p SSID is restricted to single address space, false
76  /// otherwise
77  bool isOneAddressSpace(SyncScope::ID SSID) const {
78    return SSID == getSingleThreadOneAddressSpaceSSID() ||
79        SSID == getWavefrontOneAddressSpaceSSID() ||
80        SSID == getWorkgroupOneAddressSpaceSSID() ||
81        SSID == getAgentOneAddressSpaceSSID() ||
82        SSID == getSystemOneAddressSpaceSSID();
83  }
84
85public:
86  AMDGPUMachineModuleInfo(const MachineModuleInfo &MMI);
87
88  /// \returns Agent synchronization scope ID (cross address space).
89  SyncScope::ID getAgentSSID() const {
90    return AgentSSID;
91  }
92  /// \returns Workgroup synchronization scope ID (cross address space).
93  SyncScope::ID getWorkgroupSSID() const {
94    return WorkgroupSSID;
95  }
96  /// \returns Wavefront synchronization scope ID (cross address space).
97  SyncScope::ID getWavefrontSSID() const {
98    return WavefrontSSID;
99  }
100  /// \returns System synchronization scope ID (single address space).
101  SyncScope::ID getSystemOneAddressSpaceSSID() const {
102    return SystemOneAddressSpaceSSID;
103  }
104  /// \returns Agent synchronization scope ID (single address space).
105  SyncScope::ID getAgentOneAddressSpaceSSID() const {
106    return AgentOneAddressSpaceSSID;
107  }
108  /// \returns Workgroup synchronization scope ID (single address space).
109  SyncScope::ID getWorkgroupOneAddressSpaceSSID() const {
110    return WorkgroupOneAddressSpaceSSID;
111  }
112  /// \returns Wavefront synchronization scope ID (single address space).
113  SyncScope::ID getWavefrontOneAddressSpaceSSID() const {
114    return WavefrontOneAddressSpaceSSID;
115  }
116  /// \returns Single thread synchronization scope ID (single address space).
117  SyncScope::ID getSingleThreadOneAddressSpaceSSID() const {
118    return SingleThreadOneAddressSpaceSSID;
119  }
120
121  /// In AMDGPU target synchronization scopes are inclusive, meaning a
122  /// larger synchronization scope is inclusive of a smaller synchronization
123  /// scope.
124  ///
125  /// \returns True if synchronization scope \p A is larger than or equal to
126  /// synchronization scope \p B, false if synchronization scope \p A is smaller
127  /// than synchronization scope \p B, or "None" if either synchronization scope
128  /// \p A or \p B is not supported by the AMDGPU target.
129  Optional<bool> isSyncScopeInclusion(SyncScope::ID A, SyncScope::ID B) const {
130    const auto &AIO = getSyncScopeInclusionOrdering(A);
131    const auto &BIO = getSyncScopeInclusionOrdering(B);
132    if (!AIO || !BIO)
133      return None;
134
135    bool IsAOneAddressSpace = isOneAddressSpace(A);
136    bool IsBOneAddressSpace = isOneAddressSpace(B);
137
138    return AIO.getValue() >= BIO.getValue() &&
139        (IsAOneAddressSpace == IsBOneAddressSpace || !IsAOneAddressSpace);
140  }
141};
142
143} // end namespace llvm
144
145#endif // LLVM_LIB_TARGET_AMDGPU_AMDGPUMACHINEMODULEINFO_H
146