Skip to content

Commit a11308a

Browse files
committed
[SYCL] SYCL integration header emission by device compiler
Signed-off-by: Vladimir Lazarev <[email protected]>
1 parent f037419 commit a11308a

File tree

6 files changed

+530
-86
lines changed

6 files changed

+530
-86
lines changed

clang/include/clang/Basic/LangOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,9 @@ class LangOptions : public LangOptionsBase {
250250
/// input is a header file (i.e. -x c-header).
251251
bool IsHeaderFile = false;
252252

253+
/// SYCL integration header to be generated by the device compiler
254+
std::string SYCLIntHeader;
255+
253256
LangOptions();
254257

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

clang/include/clang/Driver/CC1Options.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -842,6 +842,11 @@ def fopenmp_host_ir_file_path : Separate<["-"], "fopenmp-host-ir-file-path">,
842842
def fsycl_is_device : Flag<["-"], "fsycl-is-device">,
843843
HelpText<"Generate code for SYCL device.">;
844844

845+
def fsycl_int_header : Separate<["-"], "fsycl-int-header">,
846+
HelpText<"Generate SYCL integration header into this file.">;
847+
def fsycl_int_header_EQ : Joined<["-"], "fsycl-int-header=">,
848+
Alias<fsycl_int_header>;
849+
845850
} // let Flags = [CC1Option]
846851

847852
//===----------------------------------------------------------------------===//

clang/include/clang/Sema/Sema.h

Lines changed: 106 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,101 @@ class FileNullabilityMap {
274274
}
275275
};
276276

277+
// TODO SYCL Integration header approach relies on an assumption that kernel
278+
// lambda objects created by the host compiler and any of the device compilers
279+
// will be identical wrt to field types, order and offsets. Some verification
280+
// mechanism should be developed to enforce that.
281+
282+
// TODO FIXME SYCL Support for SYCL in FE should be refactored:
283+
// - kernel indentification and generation should be made a separate pass over
284+
// AST. RecursiveASTVisitor + VisitFunctionTemplateDecl +
285+
// FunctionTemplateDecl::getSpecializations() mechanism could be used for that.
286+
// - All SYCL stuff on Sema level should be encapsulated into a single Sema
287+
// field
288+
// - Move SYCL stuff into a separate header
289+
290+
// Represents contents of a SYCL integration header file produced by a SYCL
291+
// device compiler and used by SYCL host compiler (via forced inclusion into
292+
// compiled SYCL source):
293+
// - SYCL kernel names
294+
// - SYCL kernel parameters and offsets of corresponding actual arguments
295+
class SYCLIntegrationHeader {
296+
public:
297+
// Kind of kernel's lambda parameters as captured by the compiler in the
298+
// kernel lambda object
299+
enum kernel_param_kind_t {
300+
kind_first,
301+
kind_none = kind_first,
302+
kind_accessor,
303+
kind_scalar,
304+
kind_struct,
305+
kind_sampler,
306+
kind_struct_padding, // can be added by the compiler to enforce alignment
307+
kind_last = kind_struct_padding
308+
};
309+
310+
public:
311+
SYCLIntegrationHeader();
312+
313+
/// Emits contents of the header into given stream.
314+
void emit(raw_ostream &Out);
315+
316+
/// Emits contents of the header into a file with given name.
317+
/// Returns true/false on success/failure.
318+
bool emit(const StringRef &MainSrc);
319+
320+
/// Signals that subsequent parameter descriptor additions will go to
321+
/// the kernel with given name. Starts new kernel invocation descriptor.
322+
void startKernel(StringRef KernelName);
323+
324+
/// Adds a kernel parameter descriptor to current kernel invocation
325+
/// descriptor.
326+
void addParamDesc(kernel_param_kind_t Kind, int Info, unsigned Offset);
327+
328+
/// Signals that addition of parameter descriptors to current kernel
329+
/// invocation descriptor has finished.
330+
void endKernel();
331+
332+
private:
333+
// Kernel actual parameter descriptor.
334+
struct KernelParamDesc {
335+
// Represents a parameter kind.
336+
kernel_param_kind_t Kind;
337+
// If Kind is kind_scalar or kind_struct, then
338+
// denotes parameter size in bytes (includes padding for structs)
339+
// If Kind is kind_accessor
340+
// denotes access target; possible access targets are defined in
341+
// access/access.hpp
342+
int Info;
343+
// Offset of the captured parameter value in the lambda or function object.
344+
unsigned Offset;
345+
346+
KernelParamDesc() = default;
347+
};
348+
349+
// Kernel invocation descriptor
350+
struct KernelDesc {
351+
/// Kernel name.
352+
std::string Name;
353+
/// Descriptor of kernel actual parameters.
354+
SmallVector<KernelParamDesc, 8> Params;
355+
356+
KernelDesc() = default;
357+
};
358+
359+
/// Returns the latest invocation descriptor started by
360+
/// SYCLIntegrationHeader::startKernel
361+
KernelDesc *getCurKernelDesc() {
362+
return KernelDescs.size() > 0 ? &KernelDescs[KernelDescs.size() - 1]
363+
: nullptr;
364+
}
365+
366+
private:
367+
/// Keeps invocation descriptors for each kernel invocation started by
368+
/// SYCLIntegrationHeader::startKernel
369+
SmallVector<KernelDesc, 4> KernelDescs;
370+
};
371+
277372
/// Sema - This implements semantic analysis and AST building for C.
278373
class Sema {
279374
Sema(const Sema &) = delete;
@@ -10847,12 +10942,22 @@ class Sema {
1084710942
// We store SYCL Kernels here and handle separately -- which is a hack.
1084810943
// FIXME: It would be best to refactor this.
1084910944
SmallVector<Decl*, 4> SyclKernel;
10945+
// SYCL integratrion header instance for current compilation unit this Sema
10946+
// is associated with.
10947+
std::unique_ptr<SYCLIntegrationHeader> SyclIntHeader;
1085010948

1085110949
public:
1085210950
void AddSyclKernel(Decl * d) { SyclKernel.push_back(d); }
1085310951
SmallVector<Decl*, 4> &SyclKernels() { return SyclKernel; }
1085410952

10855-
void ConstructSYCLKernel(FunctionDecl* KernelHelper);
10953+
/// Lazily creates and returns SYCL integratrion header instance.
10954+
SYCLIntegrationHeader &getSyclIntegrationHeader() {
10955+
if (SyclIntHeader == nullptr)
10956+
SyclIntHeader = llvm::make_unique<SYCLIntegrationHeader>();
10957+
return *SyclIntHeader.get();
10958+
}
10959+
10960+
void ConstructSYCLKernel(FunctionDecl *KernelCallerFunc);
1085610961
};
1085710962

1085810963
/// RAII object that enters a new expression evaluation context.

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2398,6 +2398,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
23982398

23992399
Opts.GPURelocatableDeviceCode = Args.hasArg(OPT_fgpu_rdc);
24002400

2401+
Opts.SYCLIntHeader = Args.getLastArgValue(OPT_fsycl_int_header);
2402+
24012403
if (Opts.ObjC) {
24022404
if (Arg *arg = Args.getLastArg(OPT_fobjc_runtime_EQ)) {
24032405
StringRef value = arg->getValue();

clang/lib/Sema/Sema.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,8 @@ Sema::Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer,
145145
CurrentInstantiationScope(nullptr), DisableTypoCorrection(false),
146146
TyposCorrected(0), AnalysisWarnings(*this),
147147
ThreadSafetyDeclCache(nullptr), VarDataSharingAttributesStack(nullptr),
148-
CurScope(nullptr), Ident_super(nullptr), Ident___float128(nullptr) {
148+
CurScope(nullptr), Ident_super(nullptr), Ident___float128(nullptr),
149+
SyclIntHeader(nullptr) {
149150
TUScope = nullptr;
150151

151152
LoadedExternalKnownNamespaces = false;
@@ -916,6 +917,11 @@ void Sema::ActOnEndOfTranslationUnit() {
916917

917918
PerformPendingInstantiations();
918919

920+
// Emit SYCL integration header for current translation unit if needed
921+
if (getLangOpts().SYCL && SyclIntHeader != nullptr) {
922+
SyclIntHeader->emit(getLangOpts().SYCLIntHeader);
923+
}
924+
919925
assert(LateParsedInstantiations.empty() &&
920926
"end of TU template instantiation should not create more "
921927
"late-parsed templates");

0 commit comments

Comments
 (0)