Skip to content

Commit 3670b79

Browse files
author
Alexander Johnston
committed
[SYCL][CUDA] Change __spirv_BuiltIn.. to functions
Changes the following builtins to functions __spirv_BuiltInGlobalSize __spirv_BuiltInWorkgroupSize __spirv_BuiltInNumWorkgroups __spirv_BuiltInLocalInvocationId __spirv_BuiltInWorkgroupId __spirv_BuiltInGlobalOffset Contributors David Wood <[email protected]> Signed-off-by: Alexander Johnston <[email protected]>
1 parent d221363 commit 3670b79

File tree

6 files changed

+161
-9
lines changed

6 files changed

+161
-9
lines changed

llvm-spirv/lib/SPIRV/OCL20ToSPIRV.cpp

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -273,11 +273,31 @@ class OCL20ToSPIRV : public ModulePass, public InstVisitor<OCL20ToSPIRV> {
273273
Module *M;
274274
LLVMContext *Ctx;
275275
unsigned CLVer; /// OpenCL version as major*10+minor
276+
unsigned CLLang; /// OpenCL language, see `spv::SourceLanguage`.
276277
std::set<Value *> ValuesToDelete;
277278

278279
ConstantInt *addInt32(int I) { return getInt32(M, I); }
279280
ConstantInt *addSizet(uint64_t I) { return getSizet(M, I); }
280281

282+
/// Return the index of the id dimension represented by the demangled built-in name.
283+
/// ie. given `__spirv__GlobalInvocationId_x`, return `0`.
284+
Optional<uint64_t> spirvDimensionFromBuiltin(StringRef Name) {
285+
if (!Name.startswith("__spirv_")) {
286+
return {};
287+
}
288+
289+
Optional<uint64_t> Result = {};
290+
if (Name.endswith("_x")) {
291+
Result = 0;
292+
} else if (Name.endswith("_y")) {
293+
Result = 1;
294+
} else if (Name.endswith("_z")) {
295+
Result = 2;
296+
}
297+
298+
return Result;
299+
}
300+
281301
/// Get vector width from OpenCL vload* function name.
282302
SPIRVWord getVecLoadWidth(const std::string &DemangledName) {
283303
SPIRVWord Width = 0;
@@ -327,7 +347,8 @@ bool OCL20ToSPIRV::runOnModule(Module &Module) {
327347
M = &Module;
328348
Ctx = &M->getContext();
329349
auto Src = getSPIRVSource(&Module);
330-
if (std::get<0>(Src) != spv::SourceLanguageOpenCL_C)
350+
CLLang = std::get<0>(Src);
351+
if (CLLang != spv::SourceLanguageOpenCL_C && CLLang != spv::SourceLanguageOpenCL_CPP)
331352
return false;
332353

333354
CLVer = std::get<1>(Src);
@@ -1224,9 +1245,18 @@ void OCL20ToSPIRV::transWorkItemBuiltinsToVariables() {
12241245
std::vector<Function *> WorkList;
12251246
for (auto &I : *M) {
12261247
StringRef DemangledName;
1227-
if (!oclIsBuiltin(I.getName(), DemangledName))
1248+
auto MangledName = I.getName();
1249+
LLVM_DEBUG(dbgs() << "Function mangled name: " << MangledName << '\n');
1250+
if (!oclIsBuiltin(MangledName, DemangledName))
12281251
continue;
12291252
LLVM_DEBUG(dbgs() << "Function demangled name: " << DemangledName << '\n');
1253+
auto SpirvDimension {spirvDimensionFromBuiltin(DemangledName)};
1254+
auto IsSpirvBuiltinWithDimensions {SpirvDimension.hasValue()};
1255+
if ((!IsSpirvBuiltinWithDimensions && CLLang == spv::SourceLanguageOpenCL_CPP) ||
1256+
(IsSpirvBuiltinWithDimensions && CLLang == spv::SourceLanguageOpenCL_C)) {
1257+
// Only transform `__spirv_` builtins in OpenCL C++.
1258+
continue;
1259+
}
12301260
std::string BuiltinVarName;
12311261
SPIRVBuiltinVariableKind BVKind;
12321262
if (!SPIRSPIRVBuiltinVariableMap::find(DemangledName.str(), &BVKind))
@@ -1235,11 +1265,15 @@ void OCL20ToSPIRV::transWorkItemBuiltinsToVariables() {
12351265
std::string(kSPIRVName::Prefix) + SPIRVBuiltInNameMap::map(BVKind);
12361266
LLVM_DEBUG(dbgs() << "builtin variable name: " << BuiltinVarName << '\n');
12371267
bool IsVec = I.getFunctionType()->getNumParams() > 0;
1238-
Type *GVType =
1239-
IsVec ? VectorType::get(I.getReturnType(), 3) : I.getReturnType();
1240-
auto BV = new GlobalVariable(*M, GVType, true, GlobalValue::ExternalLinkage,
1241-
nullptr, BuiltinVarName, 0,
1242-
GlobalVariable::NotThreadLocal, SPIRAS_Input);
1268+
Type *GVType = (IsVec || IsSpirvBuiltinWithDimensions) ?
1269+
VectorType::get(I.getReturnType(), 3) : I.getReturnType();
1270+
// Each of the `__spirv__GlobalInvocationId_*` functions all extract an element of
1271+
// the same global variable, so ensure that we only create the global once.
1272+
auto BV = M->getOrInsertGlobal(BuiltinVarName, GVType, [&] {
1273+
return new GlobalVariable(
1274+
*M, GVType, true, GlobalValue::ExternalLinkage, nullptr, BuiltinVarName,
1275+
0, GlobalVariable::NotThreadLocal, SPIRAS_Input);
1276+
});
12431277
std::vector<Instruction *> InstList;
12441278
for (auto UI = I.user_begin(), UE = I.user_end(); UI != UE; ++UI) {
12451279
auto CI = dyn_cast<CallInst>(*UI);
@@ -1250,6 +1284,10 @@ void OCL20ToSPIRV::transWorkItemBuiltinsToVariables() {
12501284
NewValue =
12511285
ExtractElementInst::Create(NewValue, CI->getArgOperand(0), "", CI);
12521286
LLVM_DEBUG(dbgs() << *NewValue << '\n');
1287+
} else if (IsSpirvBuiltinWithDimensions) {
1288+
auto Index = ConstantInt::get(I.getReturnType(), SpirvDimension.getValue(), false);
1289+
NewValue = ExtractElementInst::Create(NewValue, Index, "", CI);
1290+
LLVM_DEBUG(dbgs() << *NewValue << '\n');
12531291
}
12541292
NewValue->takeName(CI);
12551293
CI->replaceAllUsesWith(NewValue);

llvm-spirv/lib/SPIRV/OCLUtil.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -592,16 +592,46 @@ template <> inline void SPIRVMap<OclExt::Kind, SPIRVCapabilityKind>::init() {
592592
template <>
593593
inline void SPIRVMap<std::string, SPIRVBuiltinVariableKind>::init() {
594594
add("get_work_dim", BuiltInWorkDim);
595+
add("__spirv_GlobalSize_x", BuiltInGlobalSize);
596+
add("__spirv_GlobalSize_y", BuiltInGlobalSize);
597+
add("__spirv_GlobalSize_z", BuiltInGlobalSize);
595598
add("get_global_size", BuiltInGlobalSize);
599+
add("__spirv_GlobalInvocationId_x", BuiltInGlobalInvocationId);
600+
add("__spirv_GlobalInvocationId_y", BuiltInGlobalInvocationId);
601+
add("__spirv_GlobalInvocationId_z", BuiltInGlobalInvocationId);
596602
add("get_global_id", BuiltInGlobalInvocationId);
603+
add("__spirv_GlobalOffset_x", BuiltInGlobalOffset);
604+
add("__spirv_GlobalOffset_y", BuiltInGlobalOffset);
605+
add("__spirv_GlobalOffset_z", BuiltInGlobalOffset);
597606
add("get_global_offset", BuiltInGlobalOffset);
607+
add("__spirv_WorkgroupSize_x", BuiltInWorkgroupSize);
608+
add("__spirv_WorkgroupSize_y", BuiltInWorkgroupSize);
609+
add("__spirv_WorkgroupSize_z", BuiltInWorkgroupSize);
598610
add("get_local_size", BuiltInWorkgroupSize);
611+
add("__spirv_WorkgroupSize_x", BuiltInWorkgroupSize);
612+
add("__spirv_WorkgroupSize_y", BuiltInWorkgroupSize);
613+
add("__spirv_WorkgroupSize_z", BuiltInWorkgroupSize);
599614
add("get_enqueued_local_size", BuiltInEnqueuedWorkgroupSize);
615+
add("__spirv_LocalInvocationId_x", BuiltInLocalInvocationId);
616+
add("__spirv_LocalInvocationId_y", BuiltInLocalInvocationId);
617+
add("__spirv_LocalInvocationId_z", BuiltInLocalInvocationId);
600618
add("get_local_id", BuiltInLocalInvocationId);
619+
add("__spirv_NumWorkgroups_x", BuiltInNumWorkgroups);
620+
add("__spirv_NumWorkgroups_y", BuiltInNumWorkgroups);
621+
add("__spirv_NumWorkgroups_z", BuiltInNumWorkgroups);
601622
add("get_num_groups", BuiltInNumWorkgroups);
623+
add("__spirv_WorkgroupId_x", BuiltInWorkgroupId);
624+
add("__spirv_WorkgroupId_y", BuiltInWorkgroupId);
625+
add("__spirv_WorkgroupId_z", BuiltInWorkgroupId);
602626
add("get_group_id", BuiltInWorkgroupId);
627+
add("__spirv_WorkgroupId_x", BuiltInWorkgroupId);
628+
add("__spirv_WorkgroupId_y", BuiltInWorkgroupId);
629+
add("__spirv_WorkgroupId_z", BuiltInWorkgroupId);
603630
add("get_global_linear_id", BuiltInGlobalLinearId);
604631
add("get_local_linear_id", BuiltInLocalInvocationIndex);
632+
add("__spirv_LocalInvocationId_x", BuiltInLocalInvocationId);
633+
add("__spirv_LocalInvocationId_y", BuiltInLocalInvocationId);
634+
add("__spirv_LocalInvocationId_z", BuiltInLocalInvocationId);
605635
add("get_sub_group_size", BuiltInSubgroupSize);
606636
add("get_max_sub_group_size", BuiltInSubgroupMaxSize);
607637
add("get_num_sub_groups", BuiltInNumSubgroups);

llvm-spirv/lib/SPIRV/SPIRVUtil.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,8 @@ bool oclIsBuiltin(StringRef Name, StringRef &DemangledName, bool IsCpp) {
489489
// Similar to ::std:: in C++.
490490
if (IsCpp) {
491491
if (!Name.startswith("_ZN"))
492+
// Attempt to demangle as C. This is useful for "extern C" functions
493+
// that have manually mangled names.
492494
return false;
493495
// Skip CV and ref qualifiers.
494496
size_t NameSpaceStart = Name.find_first_not_of("rVKRO", 3);
@@ -507,7 +509,7 @@ bool oclIsBuiltin(StringRef Name, StringRef &DemangledName, bool IsCpp) {
507509
Name.substr(2, Start - 2).getAsInteger(10, Len);
508510
DemangledName = Name.substr(Start, Len);
509511
}
510-
return true;
512+
return DemangledName.size() != 0;
511513
}
512514

513515
// Check if a mangled type Name is unsigned

llvm-spirv/lib/SPIRV/libSPIRV/spirv.hpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1157,4 +1157,3 @@ inline KernelProfilingInfoMask operator|(KernelProfilingInfoMask a, KernelProfil
11571157
} // end namespace spv
11581158

11591159
#endif // #ifndef spirv_HPP
1160-
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
; RUN: llvm-as < %s | llvm-spirv -spirv-text -o %t
2+
; RUN: FileCheck < %t %s
3+
4+
; ModuleID = 'test.cl'
5+
target datalayout = "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
6+
target triple = "spir-unknown-unknown"
7+
8+
; Check that only OpenCL builtins are translated in OpenCL C.
9+
10+
; Make sure that OCL builtins *are not* translated.
11+
; CHECK: {{[0-9]+}} Name {{[0-9]+}} "__spirv_BuiltInGlobalInvocationId"
12+
declare dso_local spir_func i64 @_Z13get_global_idj() #6
13+
14+
; Make sure that `__spirv` builtins *are not* translated.
15+
; CHECK: {{[0-9]+}} Name {{[0-9]+}} "_Z28__spirv_GlobalInvocationId_xv"
16+
declare dso_local spir_func i64 @_Z28__spirv_GlobalInvocationId_xv() #6
17+
18+
; Function Attrs: nounwind
19+
define spir_func void @foo() #0 {
20+
entry:
21+
tail call spir_func i64 @_Z28__spirv_GlobalInvocationId_xv() #2
22+
tail call spir_func i64 @_Z13get_global_idj() #2
23+
ret void
24+
}
25+
26+
!opencl.enable.FP_CONTRACT = !{}
27+
!opencl.spir.version = !{!6}
28+
!opencl.ocl.version = !{!7}
29+
!opencl.used.extensions = !{!8}
30+
!opencl.used.optional.core.features = !{!8}
31+
!opencl.compiler.options = !{!8}
32+
!llvm.ident = !{!9}
33+
!spirv.Source = !{!10}
34+
!spirv.String = !{!11}
35+
36+
!6 = !{i32 1, i32 2}
37+
!7 = !{i32 2, i32 1}
38+
!8 = !{}
39+
!9 = !{!"clang version 3.6.1 "}
40+
!10 = !{i32 3, i32 200000, !11}
41+
!11 = !{!"test.cl"}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
; RUN: llvm-as < %s | llvm-spirv -spirv-text -o %t
2+
; RUN: FileCheck < %t %s
3+
4+
; ModuleID = 'test.cl'
5+
target datalayout = "e-p:32:32-i64:64-v16:16-v24:32-v32:32-v48:64-v96:128-v192:256-v256:256-v512:512-v1024:1024"
6+
target triple = "spir-unknown-unknown"
7+
8+
; Check that only `__spirv` builtins are translated in OpenCL C++.
9+
10+
; Make sure that `__spirv` builtins *are* translated.
11+
; CHECK: {{[0-9]+}} Name 5 "__spirv_BuiltInGlobalInvocationId"
12+
declare dso_local spir_func i64 @_Z28__spirv_GlobalInvocationId_xv() #6
13+
14+
; Make sure that OCL builtins *are not* translated.
15+
; CHECK: {{[0-9]+}} Name 7 "_Z13get_global_idj"
16+
declare dso_local spir_func i64 @_Z13get_global_idj() #6
17+
18+
; Function Attrs: nounwind
19+
define spir_func void @foo() #0 {
20+
entry:
21+
tail call spir_func i64 @_Z28__spirv_GlobalInvocationId_xv() #2
22+
tail call spir_func i64 @_Z13get_global_idj() #2
23+
ret void
24+
}
25+
26+
!opencl.enable.FP_CONTRACT = !{}
27+
!opencl.spir.version = !{!6}
28+
!opencl.ocl.version = !{!7}
29+
!opencl.used.extensions = !{!8}
30+
!opencl.used.optional.core.features = !{!8}
31+
!opencl.compiler.options = !{!8}
32+
!llvm.ident = !{!9}
33+
!spirv.Source = !{!10}
34+
!spirv.String = !{!11}
35+
36+
!6 = !{i32 1, i32 2}
37+
!7 = !{i32 2, i32 1}
38+
!8 = !{}
39+
!9 = !{!"clang version 3.6.1 "}
40+
; 4 = OpenCL C++
41+
!10 = !{i32 4, i32 200000, !11}
42+
!11 = !{!"test.cl"}

0 commit comments

Comments
 (0)