Skip to content

Commit 50732ff

Browse files
author
Erich Keane
committed
[SYCL] Add infrastructure for post-integration header
We need a separate header that the driver will insert at the end of host translation unit to support SYCL 2020 spec-constants and is_device_copyable (plus potentially more in the future). This patch puts the infrastructure together so that these things can be added when final specifications are available, and so that the driver can implement their component.
1 parent 56b3ec1 commit 50732ff

File tree

7 files changed

+100
-27
lines changed

7 files changed

+100
-27
lines changed

clang/include/clang/Basic/LangOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,9 @@ class LangOptions : public LangOptionsBase {
350350
/// SYCL integration header to be generated by the device compiler
351351
std::string SYCLIntHeader;
352352

353+
/// SYCL post integration header to be generated by the device compiler
354+
std::string SYCLPostIntHeader;
355+
353356
LangOptions();
354357

355358
// Define accessors/mutators for language options of enumeration type.

clang/include/clang/Driver/Options.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5685,6 +5685,11 @@ def fsycl_int_header : Separate<["-"], "fsycl-int-header">,
56855685
MarshallingInfoString<LangOpts<"SYCLIntHeader">>;
56865686
def fsycl_int_header_EQ : Joined<["-"], "fsycl-int-header=">,
56875687
Alias<fsycl_int_header>;
5688+
def fsycl_post_int_header : Separate<["-"], "fsycl-post-int-header">,
5689+
HelpText<"Generate SYCL post integration header into this file.">,
5690+
MarshallingInfoString<LangOpts<"SYCLPostIntHeader">>;
5691+
def fsycl_post_int_header_EQ : Joined<["-"], "fsycl-post-int-header=">,
5692+
Alias<fsycl_post_int_header>;
56885693
def fsycl_std_layout_kernel_params: Flag<["-"], "fsycl-std-layout-kernel-params">,
56895694
HelpText<"Enable standard layout requirement for SYCL kernel parameters.">,
56905695
MarshallingInfoFlag<LangOpts<"SYCLStdLayoutKernelParams">>;

clang/include/clang/Sema/Sema.h

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -320,15 +320,14 @@ class SYCLIntegrationHeader {
320320
};
321321

322322
public:
323-
SYCLIntegrationHeader(DiagnosticsEngine &Diag, bool UnnamedLambdaSupport,
324-
Sema &S);
323+
SYCLIntegrationHeader(bool UnnamedLambdaSupport, Sema &S);
325324

326325
/// Emits contents of the header into given stream.
327326
void emit(raw_ostream &Out);
328327

329328
/// Emits contents of the header into a file with given name.
330329
/// Returns true/false on success/failure.
331-
bool emit(const StringRef &MainSrc);
330+
bool emit(StringRef MainSrc);
332331

333332
/// Signals that subsequent parameter descriptor additions will go to
334333
/// the kernel with given name. Starts new kernel invocation descriptor.
@@ -431,6 +430,16 @@ class SYCLIntegrationHeader {
431430
Sema &S;
432431
};
433432

433+
class SYCLPostIntegrationHeader {
434+
public:
435+
SYCLPostIntegrationHeader(Sema &S) : S(S) {}
436+
bool emit(StringRef MainSrc);
437+
438+
private:
439+
bool emit(raw_ostream &O);
440+
Sema &S;
441+
};
442+
434443
/// Tracks expected type during expression parsing, for use in code completion.
435444
/// The type is tied to a particular token, all functions that update or consume
436445
/// the type take a start location of the token they are looking at as a
@@ -13110,6 +13119,7 @@ class Sema final {
1311013119
// SYCL integration header instance for current compilation unit this Sema
1311113120
// is associated with.
1311213121
std::unique_ptr<SYCLIntegrationHeader> SyclIntHeader;
13122+
std::unique_ptr<SYCLPostIntegrationHeader> SyclPostIntHeader;
1311313123

1311413124
// Used to suppress diagnostics during kernel construction, since these were
1311513125
// already emitted earlier. Diagnosing during Kernel emissions also skips the
@@ -13124,10 +13134,16 @@ class Sema final {
1312413134
SYCLIntegrationHeader &getSyclIntegrationHeader() {
1312513135
if (SyclIntHeader == nullptr)
1312613136
SyclIntHeader = std::make_unique<SYCLIntegrationHeader>(
13127-
getDiagnostics(), getLangOpts().SYCLUnnamedLambda, *this);
13137+
getLangOpts().SYCLUnnamedLambda, *this);
1312813138
return *SyclIntHeader.get();
1312913139
}
1313013140

13141+
SYCLPostIntegrationHeader &getSyclPostIntegrationHeader() {
13142+
if (SyclPostIntHeader == nullptr)
13143+
SyclPostIntHeader = std::make_unique<SYCLPostIntegrationHeader>(*this);
13144+
return *SyclPostIntHeader.get();
13145+
}
13146+
1313113147
enum SYCLRestrictKind {
1313213148
KernelGlobalVariable,
1313313149
KernelRTTI,

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3698,8 +3698,8 @@ bool CompilerInvocation::ParseLangArgs(LangOptions &Opts, ArgList &Args,
36983698
// '-mignore-xcoff-visibility' is implied. The generated command line will
36993699
// contain both '-fvisibility default' and '-mignore-xcoff-visibility' and
37003700
// subsequent calls to `CreateFromArgs`/`generateCC1CommandLine` will always
3701-
// produce the same arguments.
3702-
3701+
// produce the same arguments.
3702+
37033703
if (T.isOSAIX() && (Args.hasArg(OPT_mignore_xcoff_visibility) ||
37043704
!Args.hasArg(OPT_fvisibility)))
37053705
Opts.IgnoreXCOFFVisibility = 1;
@@ -4291,6 +4291,22 @@ static bool ParseTargetArgs(TargetOptions &Opts, ArgList &Args,
42914291
return Success && Diags.getNumErrors() == NumErrorsBefore;
42924292
}
42934293

4294+
static void CreateEmptyFile(StringRef HeaderName) {
4295+
if (HeaderName.empty())
4296+
return;
4297+
4298+
Expected<llvm::sys::fs::file_t> ft = llvm::sys::fs::openNativeFileForWrite(
4299+
HeaderName, llvm::sys::fs::CD_OpenAlways, llvm::sys::fs::OF_None);
4300+
if (ft)
4301+
llvm::sys::fs::closeFile(*ft);
4302+
else {
4303+
// Emit a message but don't terminate; compilation will fail
4304+
// later if this file is absent.
4305+
llvm::errs() << "Error: " << llvm::toString(ft.takeError())
4306+
<< " when opening " << HeaderName << "\n";
4307+
}
4308+
}
4309+
42944310
bool CompilerInvocation::CreateFromArgsImpl(
42954311
CompilerInvocation &Res, ArrayRef<const char *> CommandLineArgs,
42964312
DiagnosticsEngine &Diags, const char *Argv0) {
@@ -4372,21 +4388,9 @@ bool CompilerInvocation::CreateFromArgsImpl(
43724388
if (LangOpts.SYCLIsDevice) {
43734389
// Set the triple of the host for SYCL device compile.
43744390
Res.getTargetOpts().HostTriple = Res.getFrontendOpts().AuxTriple;
4375-
// If specified, create an empty integration header file for now.
4376-
const StringRef &HeaderName = LangOpts.SYCLIntHeader;
4377-
if (!HeaderName.empty()) {
4378-
Expected<llvm::sys::fs::file_t> ft =
4379-
llvm::sys::fs::openNativeFileForWrite(
4380-
HeaderName, llvm::sys::fs::CD_OpenAlways, llvm::sys::fs::OF_None);
4381-
if (ft)
4382-
llvm::sys::fs::closeFile(*ft);
4383-
else {
4384-
// Emit a message but don't terminate; compilation will fail
4385-
// later if this file is absent.
4386-
llvm::errs() << "Error: " << llvm::toString(ft.takeError())
4387-
<< " when opening " << HeaderName << "\n";
4388-
}
4389-
}
4391+
// If specified, create empty integration header files for now.
4392+
CreateEmptyFile(LangOpts.SYCLIntHeader);
4393+
CreateEmptyFile(LangOpts.SYCLPostIntHeader);
43904394
}
43914395

43924396
Success &= ParseCodeGenArgs(Res.getCodeGenOpts(), Args, DashX, Diags, T,

clang/lib/Sema/Sema.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
183183
DisableTypoCorrection(false), TyposCorrected(0), AnalysisWarnings(*this),
184184
ThreadSafetyDeclCache(nullptr), VarDataSharingAttributesStack(nullptr),
185185
CurScope(nullptr), Ident_super(nullptr), Ident___float128(nullptr),
186-
SyclIntHeader(nullptr) {
186+
SyclIntHeader(nullptr), SyclPostIntHeader(nullptr) {
187187
TUScope = nullptr;
188188
isConstantEvaluatedOverride = false;
189189

@@ -1037,6 +1037,8 @@ void Sema::ActOnEndOfTranslationUnitFragment(TUFragmentKind Kind) {
10371037
// Emit SYCL integration header for current translation unit if needed
10381038
if (SyclIntHeader != nullptr)
10391039
SyclIntHeader->emit(getLangOpts().SYCLIntHeader);
1040+
if (SyclPostIntHeader != nullptr)
1041+
SyclPostIntHeader->emit(getLangOpts().SYCLPostIntHeader);
10401042
MarkDevice();
10411043
}
10421044

clang/lib/Sema/SemaSYCL.cpp

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3086,6 +3086,14 @@ class SyclKernelIntHeaderCreator : public SyclKernelFieldHandler {
30863086
using SyclKernelFieldHandler::leaveStruct;
30873087
};
30883088

3089+
class SyclKernelPostIntHeaderCreator : public SyclKernelFieldHandler {
3090+
SYCLPostIntegrationHeader &Header;
3091+
3092+
public:
3093+
SyclKernelPostIntHeaderCreator(Sema &S, SYCLPostIntegrationHeader &H)
3094+
: SyclKernelFieldHandler(S), Header(H) {}
3095+
};
3096+
30893097
} // namespace
30903098

30913099
class SYCLKernelNameTypeVisitor
@@ -3411,9 +3419,14 @@ void Sema::ConstructOpenCLKernel(FunctionDecl *KernelCallerFunc,
34113419
calculateKernelNameType(Context, KernelCallerFunc), KernelName,
34123420
StableName, KernelCallerFunc);
34133421

3422+
SyclKernelPostIntHeaderCreator post_int_header(
3423+
*this, getSyclPostIntegrationHeader());
3424+
34143425
KernelObjVisitor Visitor{*this};
3415-
Visitor.VisitRecordBases(KernelObj, kernel_decl, kernel_body, int_header);
3416-
Visitor.VisitRecordFields(KernelObj, kernel_decl, kernel_body, int_header);
3426+
Visitor.VisitRecordBases(KernelObj, kernel_decl, kernel_body, int_header,
3427+
post_int_header);
3428+
Visitor.VisitRecordFields(KernelObj, kernel_decl, kernel_body, int_header,
3429+
post_int_header);
34173430

34183431
if (ParmVarDecl *KernelHandlerArg =
34193432
getSyclKernelHandlerArg(KernelCallerFunc)) {
@@ -4149,7 +4162,7 @@ void SYCLIntegrationHeader::emit(raw_ostream &O) {
41494162
O << "\n";
41504163
}
41514164

4152-
bool SYCLIntegrationHeader::emit(const StringRef &IntHeaderName) {
4165+
bool SYCLIntegrationHeader::emit(StringRef IntHeaderName) {
41534166
if (IntHeaderName.empty())
41544167
return false;
41554168
int IntHeaderFD = 0;
@@ -4221,11 +4234,31 @@ void SYCLIntegrationHeader::setCallsThisGroup(bool B) {
42214234
K->FreeFunctionCalls.CallsThisGroup = B;
42224235
}
42234236

4224-
SYCLIntegrationHeader::SYCLIntegrationHeader(DiagnosticsEngine &_Diag,
4225-
bool _UnnamedLambdaSupport,
4237+
SYCLIntegrationHeader::SYCLIntegrationHeader(bool _UnnamedLambdaSupport,
42264238
Sema &_S)
42274239
: UnnamedLambdaSupport(_UnnamedLambdaSupport), S(_S) {}
42284240

4241+
// Post-compile integration header support.
4242+
bool SYCLPostIntegrationHeader::emit(StringRef IntHeaderName) {
4243+
if (IntHeaderName.empty())
4244+
return false;
4245+
int IntHeaderFD = 0;
4246+
std::error_code EC =
4247+
llvm::sys::fs::openFileForWrite(IntHeaderName, IntHeaderFD);
4248+
if (EC) {
4249+
llvm::errs() << "Error: " << EC.message() << "\n";
4250+
// compilation will fail on absent include file - don't need to fail here
4251+
return false;
4252+
}
4253+
llvm::raw_fd_ostream Out(IntHeaderFD, true /*close in destructor*/);
4254+
return emit(Out);
4255+
}
4256+
4257+
bool SYCLPostIntegrationHeader::emit(raw_ostream &O) {
4258+
O << "// Post Integration Header contents to go here.\n";
4259+
return true;
4260+
}
4261+
42294262
// -----------------------------------------------------------------------------
42304263
// Utility class methods
42314264
// -----------------------------------------------------------------------------
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// RUN: %clang_cc1 -fsycl-is-device -triple spir64-unknown-unknown-sycldevice -fsycl-post-int-header=%t.h %s -emit-llvm -o %t.ll
2+
// RUN: FileCheck -input-file=%t.h %s
3+
4+
// CHECK: // Post Integration Header contents to go here.
5+
6+
#include "Inputs/sycl.hpp"
7+
8+
int main() {
9+
cl::sycl::kernel_single_task<class first_kernel>([]() {});
10+
}

0 commit comments

Comments
 (0)