clang 24.0.0git
CodeGenSYCL.cpp
Go to the documentation of this file.
1//===--------- CodeGenSYCL.cpp - Code for SYCL kernel generation ----------===//
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//
9// This contains code required for generation of SYCL kernel caller offload
10// entry point functions.
11//
12//===----------------------------------------------------------------------===//
13
14#include "CodeGenFunction.h"
15#include "CodeGenModule.h"
17#include "llvm/Frontend/Offloading/OffloadWrapper.h"
18#include "llvm/Support/MemoryBuffer.h"
19#include "llvm/Support/VirtualFileSystem.h"
20#include <cassert>
21
22using namespace clang;
23using namespace CodeGen;
24
26 // SYCLKernelCallStmt instances are only injected in the definitions of
27 // functions declared with the sycl_kernel_entry_point attribute. ODR-use of
28 // such a function in code emitted during device compilation should be
29 // diagnosed. Thus, any attempt to emit a SYCLKernelCallStmt during device
30 // compilation indicates a missing diagnostic.
31 assert(!getLangOpts().SYCLIsDevice &&
32 "Attempt to emit a SYCL kernel call statement during device"
33 " compilation");
35}
36
37static void SetSYCLKernelAttributes(llvm::Function *Fn, CodeGenFunction &CGF) {
38 // SYCL 2020 device language restrictions require forward progress and
39 // disallow recursion.
40 Fn->setDoesNotRecurse();
42 Fn->addFnAttr(llvm::Attribute::MustProgress);
43}
44
45void CodeGenModule::EmitSYCLKernelCaller(const FunctionDecl *KernelEntryPointFn,
46 ASTContext &Ctx) {
47 assert(Ctx.getLangOpts().SYCLIsDevice &&
48 "SYCL kernel caller offload entry point functions can only be emitted"
49 " during device compilation");
50
51 const auto *KernelEntryPointAttr =
52 KernelEntryPointFn->getAttr<SYCLKernelEntryPointAttr>();
53 assert(KernelEntryPointAttr && "Missing sycl_kernel_entry_point attribute");
54 assert(!KernelEntryPointAttr->isInvalidAttr() &&
55 "sycl_kernel_entry_point attribute is invalid");
56
57 // Find the SYCLKernelCallStmt.
58 SYCLKernelCallStmt *KernelCallStmt =
59 cast<SYCLKernelCallStmt>(KernelEntryPointFn->getBody());
60
61 // Retrieve the SYCL kernel caller parameters from the OutlinedFunctionDecl.
62 FunctionArgList Args;
63 const OutlinedFunctionDecl *OutlinedFnDecl =
64 KernelCallStmt->getOutlinedFunctionDecl();
65 Args.append(OutlinedFnDecl->param_begin(), OutlinedFnDecl->param_end());
66
67 // Compute the function info and LLVM function type.
68 const CGFunctionInfo &FnInfo =
70 llvm::FunctionType *FnTy = getTypes().GetFunctionType(FnInfo);
71
72 // Retrieve the generated name for the SYCL kernel caller function.
73 CanQualType KernelNameType =
74 Ctx.getCanonicalType(KernelEntryPointAttr->getKernelName());
75 const SYCLKernelInfo &KernelInfo = Ctx.getSYCLKernelInfo(KernelNameType);
76 auto *Fn = llvm::Function::Create(FnTy, llvm::Function::ExternalLinkage,
77 KernelInfo.GetKernelName(), &getModule());
78
79 // Emit the SYCL kernel caller function.
80 CodeGenFunction CGF(*this);
81 SetLLVMFunctionAttributes(GlobalDecl(), FnInfo, Fn, false);
83 addSYCLModuleIdAttr(Fn);
84 CGF.StartFunction(GlobalDecl(), Ctx.VoidTy, Fn, FnInfo, Args,
85 SourceLocation(), SourceLocation());
86 CGF.EmitFunctionBody(OutlinedFnDecl->getBody());
87 setDSOLocal(Fn);
89 CGF.FinishFunction();
90}
91
92llvm::Function *CodeGenModule::embedSYCLDeviceBinary() {
94 auto BufferOrErr = getFileSystem()->getBufferForFile(FileName);
95 if (std::error_code EC = BufferOrErr.getError()) {
96 getDiags().Report(diag::err_cannot_open_file) << FileName << EC.message();
97 return nullptr;
98 }
99 std::unique_ptr<llvm::MemoryBuffer> Buffer = std::move(BufferOrErr.get());
100 llvm::Function *RegistrationFunc = nullptr;
101 if (llvm::Error Err = llvm::offloading::wrapSYCLBinaries(
102 getModule(),
103 ArrayRef<char>(Buffer->getBufferStart(), Buffer->getBufferSize()),
104 llvm::offloading::SYCLJITOptions(), /*IsFinalizedImage=*/true,
105 &RegistrationFunc)) {
106 getDiags().Report(diag::err_fe_error_backend)
107 << llvm::toString(std::move(Err));
108 return nullptr;
109 }
110 return RegistrationFunc;
111}
static void SetSYCLKernelAttributes(llvm::Function *Fn, CodeGenFunction &CGF)
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
const LangOptions & getLangOpts() const
Definition ASTContext.h:981
CanQualType VoidTy
const SYCLKernelInfo & getSYCLKernelInfo(QualType T) const
Given a type used as a SYCL kernel name, returns a reference to the metadata generated from the corre...
std::string OffloadBinaryToEmbedFile
Name of file passed with -foffload-include-binary option to forward to offloading runtime back-end fo...
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
const LangOptions & getLangOpts() const
void EmitStmt(const Stmt *S, ArrayRef< const Attr * > Attrs={})
EmitStmt - Emit the code for the statement.
Definition CGStmt.cpp:58
void EmitSYCLKernelCallStmt(const SYCLKernelCallStmt &S)
bool checkIfFunctionMustProgress()
Returns true if a function must make progress, which means the mustprogress attribute can be added.
void setDSOLocal(llvm::GlobalValue *GV) const
llvm::Module & getModule() const
const IntrusiveRefCntPtr< llvm::vfs::FileSystem > & getFileSystem() const
DiagnosticsEngine & getDiags() const
const CodeGenOptions & getCodeGenOpts() const
void SetLLVMFunctionAttributes(GlobalDecl GD, const CGFunctionInfo &Info, llvm::Function *F, bool IsThunk)
Set the LLVM function attributes (sext, zext, etc).
void SetLLVMFunctionAttributesForDefinition(const Decl *D, llvm::Function *F)
Set the LLVM function attributes which only apply to a function definition.
llvm::FunctionType * GetFunctionType(const CGFunctionInfo &Info)
GetFunctionType - Get the LLVM function type for.
Definition CGCall.cpp:2050
const CGFunctionInfo & arrangeDeviceKernelCallerDeclaration(QualType resultType, const FunctionArgList &args)
A device kernel caller function is an offload device entry point function with a target device depend...
Definition CGCall.cpp:795
T * getAttr() const
Definition DeclBase.h:581
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
Definition Decl.cpp:3268
parameter_const_iterator param_end() const
Definition Decl.h:5061
Stmt * getBody() const override
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
Definition Decl.cpp:5741
parameter_const_iterator param_begin() const
Definition Decl.h:5060
SYCLKernelCallStmt represents the transformation that is applied to the body of a function declared w...
Definition StmtSYCL.h:36
OutlinedFunctionDecl * getOutlinedFunctionDecl()
Definition StmtSYCL.h:66
const std::string & GetKernelName() const
Top level wrappers for InstallAPI frontend operations.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
U cast(CodeGen::Address addr)
Definition Address.h:327