LLVM 24.0.0git
AtomicScope.h
Go to the documentation of this file.
1//===-- llvm/TargetParser/AtomicScope.h ---Atomic Scope--------*- 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#ifndef LLVM_TARGETPARSER_ATOMICSCOPE_H
10#define LLVM_TARGETPARSER_ATOMICSCOPE_H
11
12#include "llvm/ADT/StringRef.h"
15#include <optional>
16#include <utility>
17
18namespace llvm {
19
20/// Target-neutral memory synchronization scopes.
21///
22/// The underlying values are ABI-sensitive and should not be changed.
23enum class AtomicScope : unsigned {
24 System = 0, // __MEMORY_SCOPE_SYSTEM
25 Device = 1, // __MEMORY_SCOPE_DEVICE
26 Workgroup = 2, // __MEMORY_SCOPE_WRKGRP
27 Wavefront = 3, // __MEMORY_SCOPE_WVFRNT
28 Single = 4, // __MEMORY_SCOPE_SINGLE
29 Cluster = 5, // __MEMORY_SCOPE_CLUSTR
30};
31
32/// Returns the LLVM IR syncscope string that \p T uses to spell \p S.
33inline std::optional<StringRef>
35 bool IsSingleAddressSpace = false) {
36 if (T.isAMDGPU()) {
37 switch (S) {
39 return IsSingleAddressSpace ? "singlethread-one-as" : "singlethread";
41 return IsSingleAddressSpace ? "wavefront-one-as" : "wavefront";
43 return IsSingleAddressSpace ? "workgroup-one-as" : "workgroup";
45 return IsSingleAddressSpace ? "cluster-one-as" : "cluster";
47 return IsSingleAddressSpace ? "agent-one-as" : "agent";
49 return IsSingleAddressSpace ? "one-as" : "";
50 }
51 return std::nullopt;
52 }
53 if (T.isNVPTX()) {
54 switch (S) {
56 return "singlethread";
57 // NVPTX has no distinct wavefront/subgroup scope; it folds into block.
60 return "block";
62 return "cluster";
64 return "device";
66 return "";
67 }
68 return std::nullopt;
69 }
70 if (T.isSPIRV()) {
71 switch (S) {
73 return "singlethread";
75 return "subgroup";
76 // SPIR-V has no cluster scope; it folds into workgroup.
79 return "workgroup";
81 return "device";
83 return "";
84 }
85 return std::nullopt;
86 }
87 return std::nullopt;
88}
89
90/// Parses an AMDGPU syncscope string into its abstract scope and whether it is
91/// the single address space variant.
92inline std::optional<std::pair<AtomicScope, bool>>
94 using Result = std::optional<std::pair<AtomicScope, bool>>;
95 auto Make = [](AtomicScope S,
96 bool IsSingleAddressSpace) -> std::pair<AtomicScope, bool> {
97 return {S, IsSingleAddressSpace};
98 };
99 return StringSwitch<Result>(Name)
100 .Case("singlethread", Make(AtomicScope::Single, false))
101 .Case("wavefront", Make(AtomicScope::Wavefront, false))
102 .Case("workgroup", Make(AtomicScope::Workgroup, false))
103 .Case("cluster", Make(AtomicScope::Cluster, false))
104 .Case("agent", Make(AtomicScope::Device, false))
105 .Case("", Make(AtomicScope::System, false))
106 .Case("singlethread-one-as", Make(AtomicScope::Single, true))
107 .Case("wavefront-one-as", Make(AtomicScope::Wavefront, true))
108 .Case("workgroup-one-as", Make(AtomicScope::Workgroup, true))
109 .Case("cluster-one-as", Make(AtomicScope::Cluster, true))
110 .Case("agent-one-as", Make(AtomicScope::Device, true))
111 .Case("one-as", Make(AtomicScope::System, true))
112 .Default(std::nullopt);
113}
114
115/// Parses a target syncscope string into its abstract scope, the inverse of
116/// getAtomicScopeIRString. Returns the scope and whether it is the single
117/// address space variant.
118inline std::optional<std::pair<AtomicScope, bool>>
120 using Result = std::optional<std::pair<AtomicScope, bool>>;
121 auto Make = [](AtomicScope S,
122 bool IsSingleAddressSpace) -> std::pair<AtomicScope, bool> {
123 return {S, IsSingleAddressSpace};
124 };
125 if (T.isAMDGPU())
127 if (T.isNVPTX())
128 return StringSwitch<Result>(Name)
129 .Case("singlethread", Make(AtomicScope::Single, false))
130 .Case("block", Make(AtomicScope::Workgroup, false))
131 .Case("cluster", Make(AtomicScope::Cluster, false))
132 .Case("device", Make(AtomicScope::Device, false))
133 .Case("", Make(AtomicScope::System, false))
134 .Default(std::nullopt);
135 if (T.isSPIRV())
136 return StringSwitch<Result>(Name)
137 .Case("singlethread", Make(AtomicScope::Single, false))
138 .Case("subgroup", Make(AtomicScope::Wavefront, false))
139 .Case("workgroup", Make(AtomicScope::Workgroup, false))
140 .Case("device", Make(AtomicScope::Device, false))
141 .Case("", Make(AtomicScope::System, false))
142 .Default(std::nullopt);
143 return std::nullopt;
144}
145
146} // end namespace llvm
147
148#endif // LLVM_TARGETPARSER_ATOMICSCOPE_H
#define T
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
This is an optimization pass for GlobalISel generic memory operations.
AtomicScope
Target-neutral memory synchronization scopes.
Definition AtomicScope.h:23
std::optional< std::pair< AtomicScope, bool > > parseAtomicScopeIRString(const Triple &T, StringRef Name)
Parses a target syncscope string into its abstract scope, the inverse of getAtomicScopeIRString.
std::optional< std::pair< AtomicScope, bool > > parseAMDGPUAtomicScopeIRString(StringRef Name)
Parses an AMDGPU syncscope string into its abstract scope and whether it is the single address space ...
Definition AtomicScope.h:93
std::optional< StringRef > getAtomicScopeIRString(const Triple &T, AtomicScope S, bool IsSingleAddressSpace=false)
Returns the LLVM IR syncscope string that T uses to spell S.
Definition AtomicScope.h:34