1//===----------------------------------------------------------------------===//
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#include "clang/Basic/OffloadArch.h"
9
10#include "llvm/ADT/STLExtras.h"
11#include "llvm/ADT/StringRef.h"
12#include "llvm/TargetParser/Triple.h"
13
14namespace clang {
15
16namespace {
17struct OffloadArchToStringMap {
18 OffloadArch Arch;
19 const char *ArchName;
20 const char *VirtualArchName;
21};
22} // namespace
23
24#define SM(sm) {OffloadArch::SM_##sm, "sm_" #sm, "compute_" #sm}
25#define GFX(gpu) {OffloadArch::GFX##gpu, "gfx" #gpu, "compute_amdgcn"}
26static const OffloadArchToStringMap ArchNames[] = {
27 // clang-format off
28 {.Arch: OffloadArch::Unused, .ArchName: "", .VirtualArchName: ""},
29 SM(20), {.Arch: OffloadArch::SM_21, .ArchName: "sm_21", .VirtualArchName: "compute_20"}, // Fermi
30 SM(30), {.Arch: OffloadArch::SM_32_, .ArchName: "sm_32", .VirtualArchName: "compute_32"}, SM(35), SM(37), // Kepler
31 SM(50), SM(52), SM(53), // Maxwell
32 SM(60), SM(61), SM(62), // Pascal
33 SM(70), SM(72), // Volta
34 SM(75), // Turing
35 SM(80), SM(86), // Ampere
36 SM(87), // Jetson/Drive AGX Orin
37 SM(88), // Ampere
38 SM(89), // Ada Lovelace
39 SM(90), // Hopper
40 SM(90a), // Hopper
41 SM(100), // Blackwell
42 SM(100a), // Blackwell
43 SM(100f), // Blackwell
44 SM(101), // Blackwell
45 SM(101a), // Blackwell
46 SM(101f), // Blackwell
47 SM(103), // Blackwell
48 SM(103a), // Blackwell
49 SM(103f), // Blackwell
50 SM(110), // Blackwell
51 SM(110a), // Blackwell
52 SM(110f), // Blackwell
53 SM(120), // Blackwell
54 SM(120a), // Blackwell
55 SM(120f), // Blackwell
56 SM(121), // Blackwell
57 SM(121a), // Blackwell
58 SM(121f), // Blackwell
59 GFX(600), // gfx600
60 GFX(601), // gfx601
61 GFX(602), // gfx602
62 GFX(700), // gfx700
63 GFX(701), // gfx701
64 GFX(702), // gfx702
65 GFX(703), // gfx703
66 GFX(704), // gfx704
67 GFX(705), // gfx705
68 GFX(801), // gfx801
69 GFX(802), // gfx802
70 GFX(803), // gfx803
71 GFX(805), // gfx805
72 GFX(810), // gfx810
73 {.Arch: OffloadArch::GFX9_GENERIC, .ArchName: "gfx9-generic", .VirtualArchName: "compute_amdgcn"},
74 GFX(900), // gfx900
75 GFX(902), // gfx902
76 GFX(904), // gfx903
77 GFX(906), // gfx906
78 GFX(908), // gfx908
79 GFX(909), // gfx909
80 GFX(90a), // gfx90a
81 GFX(90c), // gfx90c
82 {.Arch: OffloadArch::GFX9_4_GENERIC, .ArchName: "gfx9-4-generic", .VirtualArchName: "compute_amdgcn"},
83 GFX(942), // gfx942
84 GFX(950), // gfx950
85 {.Arch: OffloadArch::GFX10_1_GENERIC, .ArchName: "gfx10-1-generic", .VirtualArchName: "compute_amdgcn"},
86 GFX(1010), // gfx1010
87 GFX(1011), // gfx1011
88 GFX(1012), // gfx1012
89 GFX(1013), // gfx1013
90 {.Arch: OffloadArch::GFX10_3_GENERIC, .ArchName: "gfx10-3-generic", .VirtualArchName: "compute_amdgcn"},
91 GFX(1030), // gfx1030
92 GFX(1031), // gfx1031
93 GFX(1032), // gfx1032
94 GFX(1033), // gfx1033
95 GFX(1034), // gfx1034
96 GFX(1035), // gfx1035
97 GFX(1036), // gfx1036
98 {.Arch: OffloadArch::GFX11_GENERIC, .ArchName: "gfx11-generic", .VirtualArchName: "compute_amdgcn"},
99 GFX(1100), // gfx1100
100 GFX(1101), // gfx1101
101 GFX(1102), // gfx1102
102 GFX(1103), // gfx1103
103 GFX(1150), // gfx1150
104 GFX(1151), // gfx1151
105 GFX(1152), // gfx1152
106 GFX(1153), // gfx1153
107 GFX(1154), // gfx1154
108 {.Arch: OffloadArch::GFX11_7_GENERIC, .ArchName: "gfx11-7-generic", .VirtualArchName: "compute_amdgcn"},
109 GFX(1170), // gfx1170
110 GFX(1171), // gfx1171
111 GFX(1172), // gfx1172
112 {.Arch: OffloadArch::GFX12_GENERIC, .ArchName: "gfx12-generic", .VirtualArchName: "compute_amdgcn"},
113 GFX(1200), // gfx1200
114 GFX(1201), // gfx1201
115 {.Arch: OffloadArch::GFX12_5_GENERIC, .ArchName: "gfx12-5-generic", .VirtualArchName: "compute_amdgcn"},
116 GFX(1250), // gfx1250
117 GFX(1251), // gfx1251
118 {.Arch: OffloadArch::GFX13_GENERIC, .ArchName: "gfx13-generic", .VirtualArchName: "compute_amdgcn"},
119 GFX(1310), // gfx1310
120 {.Arch: OffloadArch::AMDGCNSPIRV, .ArchName: "amdgcnspirv", .VirtualArchName: "compute_amdgcn"},
121 // Intel CPUs
122 {.Arch: OffloadArch::GRANITERAPIDS, .ArchName: "graniterapids", .VirtualArchName: ""},
123 // Intel GPUS
124 {.Arch: OffloadArch::BMG_G21, .ArchName: "bmg_g21", .VirtualArchName: ""},
125 {.Arch: OffloadArch::Generic, .ArchName: "generic", .VirtualArchName: ""},
126 // clang-format on
127};
128#undef SM
129#undef GFX
130
131const char *OffloadArchToString(OffloadArch A) {
132 auto Result =
133 llvm::find_if(Range: ArchNames, P: [A](const OffloadArchToStringMap &Map) {
134 return A == Map.Arch;
135 });
136 if (Result == std::end(arr: ArchNames))
137 return "unknown";
138 return Result->ArchName;
139}
140
141const char *OffloadArchToVirtualArchString(OffloadArch A) {
142 auto Result =
143 llvm::find_if(Range: ArchNames, P: [A](const OffloadArchToStringMap &Map) {
144 return A == Map.Arch;
145 });
146 if (Result == std::end(arr: ArchNames))
147 return "unknown";
148 return Result->VirtualArchName;
149}
150
151OffloadArch StringToOffloadArch(llvm::StringRef S) {
152 auto Result =
153 llvm::find_if(Range: ArchNames, P: [S](const OffloadArchToStringMap &Map) {
154 return S == Map.ArchName;
155 });
156 if (Result == std::end(arr: ArchNames))
157 return OffloadArch::Unknown;
158 return Result->Arch;
159}
160
161llvm::Triple OffloadArchToTriple(const llvm::Triple &DefaultToolchainTriple,
162 OffloadArch ID) {
163 if (ID == OffloadArch::AMDGCNSPIRV)
164 return llvm::Triple(llvm::Triple::spirv64, llvm::Triple::NoSubArch,
165 llvm::Triple::AMD, llvm::Triple::AMDHSA);
166
167 if (IsNVIDIAOffloadArch(A: ID)) {
168 llvm::Triple::ArchType Arch = DefaultToolchainTriple.isArch64Bit()
169 ? llvm::Triple::nvptx64
170 : llvm::Triple::nvptx;
171 return llvm::Triple(Arch, llvm::Triple::NoSubArch, llvm::Triple::NVIDIA,
172 llvm::Triple::CUDA);
173 }
174
175 if (IsAMDOffloadArch(A: ID))
176 return llvm::Triple(llvm::Triple::amdgcn, llvm::Triple::NoSubArch,
177 llvm::Triple::AMD, llvm::Triple::AMDHSA);
178
179 return {};
180}
181
182} // namespace clang
183