73 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8//9// This contains code required for generation of SYCL kernel caller offload10// entry point functions.11//12//===----------------------------------------------------------------------===//13 14#include "CodeGenFunction.h"15#include "CodeGenModule.h"16 17using namespace clang;18using namespace CodeGen;19 20static void SetSYCLKernelAttributes(llvm::Function *Fn, CodeGenFunction &CGF) {21 // SYCL 2020 device language restrictions require forward progress and22 // disallow recursion.23 Fn->setDoesNotRecurse();24 if (CGF.checkIfFunctionMustProgress())25 Fn->addFnAttr(llvm::Attribute::MustProgress);26}27 28void CodeGenModule::EmitSYCLKernelCaller(const FunctionDecl *KernelEntryPointFn,29 ASTContext &Ctx) {30 assert(Ctx.getLangOpts().SYCLIsDevice &&31 "SYCL kernel caller offload entry point functions can only be emitted"32 " during device compilation");33 34 const auto *KernelEntryPointAttr =35 KernelEntryPointFn->getAttr<SYCLKernelEntryPointAttr>();36 assert(KernelEntryPointAttr && "Missing sycl_kernel_entry_point attribute");37 assert(!KernelEntryPointAttr->isInvalidAttr() &&38 "sycl_kernel_entry_point attribute is invalid");39 40 // Find the SYCLKernelCallStmt.41 SYCLKernelCallStmt *KernelCallStmt =42 cast<SYCLKernelCallStmt>(KernelEntryPointFn->getBody());43 44 // Retrieve the SYCL kernel caller parameters from the OutlinedFunctionDecl.45 FunctionArgList Args;46 const OutlinedFunctionDecl *OutlinedFnDecl =47 KernelCallStmt->getOutlinedFunctionDecl();48 Args.append(OutlinedFnDecl->param_begin(), OutlinedFnDecl->param_end());49 50 // Compute the function info and LLVM function type.51 const CGFunctionInfo &FnInfo =52 getTypes().arrangeDeviceKernelCallerDeclaration(Ctx.VoidTy, Args);53 llvm::FunctionType *FnTy = getTypes().GetFunctionType(FnInfo);54 55 // Retrieve the generated name for the SYCL kernel caller function.56 CanQualType KernelNameType =57 Ctx.getCanonicalType(KernelEntryPointAttr->getKernelName());58 const SYCLKernelInfo &KernelInfo = Ctx.getSYCLKernelInfo(KernelNameType);59 auto *Fn = llvm::Function::Create(FnTy, llvm::Function::ExternalLinkage,60 KernelInfo.GetKernelName(), &getModule());61 62 // Emit the SYCL kernel caller function.63 CodeGenFunction CGF(*this);64 SetLLVMFunctionAttributes(GlobalDecl(), FnInfo, Fn, false);65 SetSYCLKernelAttributes(Fn, CGF);66 CGF.StartFunction(GlobalDecl(), Ctx.VoidTy, Fn, FnInfo, Args,67 SourceLocation(), SourceLocation());68 CGF.EmitFunctionBody(OutlinedFnDecl->getBody());69 setDSOLocal(Fn);70 SetLLVMFunctionAttributesForDefinition(cast<Decl>(OutlinedFnDecl), Fn);71 CGF.FinishFunction();72}73