//===--------- CodeGenSYCL.cpp - Code for SYCL kernel generation ----------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // This contains code required for generation of SYCL kernel caller offload // entry point functions. // //===----------------------------------------------------------------------===// #include "CodeGenFunction.h" #include "CodeGenModule.h" using namespace clang; using namespace CodeGen; static void SetSYCLKernelAttributes(llvm::Function *Fn, CodeGenFunction &CGF) { // SYCL 2020 device language restrictions require forward progress and // disallow recursion. Fn->setDoesNotRecurse(); if (CGF.checkIfFunctionMustProgress()) Fn->addFnAttr(llvm::Attribute::MustProgress); } void CodeGenModule::EmitSYCLKernelCaller(const FunctionDecl *KernelEntryPointFn, ASTContext &Ctx) { assert(Ctx.getLangOpts().SYCLIsDevice && "SYCL kernel caller offload entry point functions can only be emitted" " during device compilation"); const auto *KernelEntryPointAttr = KernelEntryPointFn->getAttr(); assert(KernelEntryPointAttr && "Missing sycl_kernel_entry_point attribute"); assert(!KernelEntryPointAttr->isInvalidAttr() && "sycl_kernel_entry_point attribute is invalid"); // Find the SYCLKernelCallStmt. SYCLKernelCallStmt *KernelCallStmt = cast(KernelEntryPointFn->getBody()); // Retrieve the SYCL kernel caller parameters from the OutlinedFunctionDecl. FunctionArgList Args; const OutlinedFunctionDecl *OutlinedFnDecl = KernelCallStmt->getOutlinedFunctionDecl(); Args.append(OutlinedFnDecl->param_begin(), OutlinedFnDecl->param_end()); // Compute the function info and LLVM function type. const CGFunctionInfo &FnInfo = getTypes().arrangeSYCLKernelCallerDeclaration(Ctx.VoidTy, Args); llvm::FunctionType *FnTy = getTypes().GetFunctionType(FnInfo); // Retrieve the generated name for the SYCL kernel caller function. CanQualType KernelNameType = Ctx.getCanonicalType(KernelEntryPointAttr->getKernelName()); const SYCLKernelInfo &KernelInfo = Ctx.getSYCLKernelInfo(KernelNameType); auto *Fn = llvm::Function::Create(FnTy, llvm::Function::ExternalLinkage, KernelInfo.GetKernelName(), &getModule()); // Emit the SYCL kernel caller function. CodeGenFunction CGF(*this); SetLLVMFunctionAttributes(GlobalDecl(), FnInfo, Fn, false); SetSYCLKernelAttributes(Fn, CGF); CGF.StartFunction(GlobalDecl(), Ctx.VoidTy, Fn, FnInfo, Args, SourceLocation(), SourceLocation()); CGF.EmitFunctionBody(OutlinedFnDecl->getBody()); setDSOLocal(Fn); SetLLVMFunctionAttributesForDefinition(cast(OutlinedFnDecl), Fn); CGF.FinishFunction(); }