Skip to content

Commit a54d6d8

Browse files
authored
[SYCL] Emit integration header even if no kernels provided (#5899)
Since device_global variables can be declared in one file and used in another, it is possible to receive an input with device_global and no kernels. Make sure that integration header and footer are emitted in this case.
1 parent f364e18 commit a54d6d8

File tree

3 files changed

+53
-3
lines changed

3 files changed

+53
-3
lines changed

clang/include/clang/Sema/Sema.h

+11-2
Original file line numberDiff line numberDiff line change
@@ -359,6 +359,13 @@ class SYCLIntegrationHeader {
359359
Itr->updateKernelNames(Name, StableName);
360360
}
361361

362+
/// Signals that emission of __sycl_device_global_registration type and
363+
/// declaration of variable __sycl_device_global_registrar of this type in
364+
/// integration header is required.
365+
void addDeviceGlobalRegistration() {
366+
NeedToEmitDeviceGlobalRegistration = true;
367+
}
368+
362369
private:
363370
// Kernel actual parameter descriptor.
364371
struct KernelParamDesc {
@@ -433,21 +440,23 @@ class SYCLIntegrationHeader {
433440
llvm::SmallVector<SpecConstID, 4> SpecConsts;
434441

435442
Sema &S;
443+
444+
/// Keeps track of whether declaration of __sycl_device_global_registration
445+
/// type and __sycl_device_global_registrar variable are required to emit.
446+
bool NeedToEmitDeviceGlobalRegistration = false;
436447
};
437448

438449
class SYCLIntegrationFooter {
439450
public:
440451
SYCLIntegrationFooter(Sema &S) : S(S) {}
441452
bool emit(StringRef MainSrc);
442453
void addVarDecl(const VarDecl *VD);
443-
bool isDeviceGlobalsEmitted() { return DeviceGlobalsEmitted; }
444454

445455
private:
446456
bool emit(raw_ostream &O);
447457
Sema &S;
448458
llvm::SmallVector<const VarDecl *> GlobalVars;
449459
void emitSpecIDName(raw_ostream &O, const VarDecl *VD);
450-
bool DeviceGlobalsEmitted = false;
451460
};
452461

453462
/// Tracks expected type during expression parsing, for use in code completion.

clang/lib/Sema/SemaSYCL.cpp

+4-1
Original file line numberDiff line numberDiff line change
@@ -4653,7 +4653,7 @@ void SYCLIntegrationHeader::emit(raw_ostream &O) {
46534653
// whose sole purpose is to run its constructor before the application's
46544654
// main() function.
46554655

4656-
if (S.getSyclIntegrationFooter().isDeviceGlobalsEmitted()) {
4656+
if (NeedToEmitDeviceGlobalRegistration) {
46574657
O << "namespace {\n";
46584658

46594659
O << "class __sycl_device_global_registration {\n";
@@ -5017,6 +5017,7 @@ bool SYCLIntegrationFooter::emit(raw_ostream &OS) {
50175017

50185018
llvm::SmallSet<const VarDecl *, 8> Visited;
50195019
bool EmittedFirstSpecConstant = false;
5020+
bool DeviceGlobalsEmitted = false;
50205021

50215022
// Used to uniquely name the 'shim's as we generate the names in each
50225023
// anonymous namespace.
@@ -5100,6 +5101,8 @@ bool SYCLIntegrationFooter::emit(raw_ostream &OS) {
51005101
OS << "}\n";
51015102
OS << "} // namespace (unnamed)\n";
51025103
OS << "} // namespace sycl::detail\n";
5104+
5105+
S.getSyclIntegrationHeader().addDeviceGlobalRegistration();
51035106
}
51045107
return true;
51055108
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// RUN: %clang_cc1 -fsycl-is-device -std=c++17 -internal-isystem %S/Inputs -triple spir64-unknown-unknown -fsycl-int-footer=%t.footer.h -fsycl-int-header=%t.header.h %s -emit-llvm -o %t.ll
2+
// RUN: FileCheck -input-file=%t.footer.h %s --check-prefix=CHECK-FOOTER
3+
// RUN: FileCheck -input-file=%t.header.h %s --check-prefix=CHECK-HEADER
4+
5+
// This test checks that integration header and footer are emitted correctly
6+
// for device_global variables even without kernels.
7+
8+
#include "sycl.hpp"
9+
10+
using namespace cl::sycl::ext::oneapi;
11+
12+
// CHECK-HEADER: __SYCL_INLINE_NAMESPACE(cl) {
13+
// CHECK-HEADER-NEXT: namespace sycl {
14+
// CHECK-HEADER-NEXT: namespace detail {
15+
// CHECK-HEADER-NEXT: namespace {
16+
// CHECK-HEADER-NEXT: class __sycl_device_global_registration {
17+
// CHECK-HEADER-NEXT: public:
18+
// CHECK-HEADER-NEXT: __sycl_device_global_registration() noexcept;
19+
// CHECK-HEADER-NEXT: };
20+
// CHECK-HEADER-NEXT: __sycl_device_global_registration __sycl_device_global_registrar;
21+
// CHECK-HEADER-NEXT: } // namespace
22+
// CHECK-HEADER: } // namespace detail
23+
// CHECK-HEADER: } // namespace sycl
24+
// CHECK-HEADER: } // __SYCL_INLINE_NAMESPACE(cl)
25+
26+
// CHECK-FOOTER: #include <CL/sycl/detail/defines_elementary.hpp>
27+
28+
// CHECK-FOOTER: #include <CL/sycl/detail/device_global_map.hpp>
29+
// CHECK-FOOTER: namespace sycl::detail {
30+
// CHECK-FOOTER-NEXT: namespace {
31+
// CHECK-FOOTER-NEXT: __sycl_device_global_registration::__sycl_device_global_registration() noexcept {
32+
33+
device_global<int> Basic;
34+
// CHECK-FOOTER-NEXT: device_global_map::add((void *)&::Basic, "_Z5Basic");
35+
36+
// CHECK-FOOTER-NEXT: }
37+
// CHECK-FOOTER-NEXT: }
38+
// CHECK-FOOTER-NEXT: }

0 commit comments

Comments
 (0)