clang 24.0.0git
CIRGenSYCL.cpp
Go to the documentation of this file.
1//===--------- CIRGenSYCL.cpp - Emit CIR for SYCL kernels -----------------===//
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 the generation of SYCL kernel code.
10//
11//===----------------------------------------------------------------------===//
12
13#include "CIRGenFunction.h"
14#include "CIRGenModule.h"
15
17#include "clang/AST/Attr.h"
18#include "clang/AST/Decl.h"
20#include "clang/AST/StmtSYCL.h"
21
22#include "llvm/Support/SaveAndRestore.h"
23
24using namespace clang;
25using namespace clang::CIRGen;
26
27mlir::LogicalResult
29 // SYCLKernelCallStmt nodes are only present in the bodies of functions
30 // declared with the sycl_kernel_entry_point attribute. ODR-use of such a
31 // function in code emitted during device compilation should be diagnosed.
32 // During device compilation, the offload kernel entry point is emitted in
33 // place of such a function (see CIRGenModule::emitDeferred), so this
34 // function is only reached during host compilation.
35 assert(!getLangOpts().SYCLIsDevice &&
36 "Attempt to emit a SYCL kernel call statement during device "
37 "compilation");
38
39 // During host compilation, the kernel launch statement is emitted in place
40 // of the original function body.
41 return emitStmt(s.getKernelLaunchStmt(), /*useCurrentScope=*/true);
42}
43
44// Emit the body of a SYCL kernel caller offload entry point. Mirrors the tail
45// of generateCode, but is driven by an OutlinedFunctionDecl and an explicit
46// argument list rather than a FunctionDecl.
48 const OutlinedFunctionDecl *outlinedFnDecl, cir::FuncOp funcOp,
49 cir::FuncType funcType, FunctionArgList &args) {
50 const Stmt *body = outlinedFnDecl->getBody();
51 SourceLocation loc = outlinedFnDecl->getLocation();
52 SourceRange bodyRange = body->getSourceRange();
53
54 // Synthesized entry point: no FunctionDecl, emitted with an empty GlobalDecl.
55 curGD = GlobalDecl();
56
57 SourceLocRAIIObject fnLoc{*this, loc};
58
59 mlir::Location fusedLoc = getLoc(bodyRange);
60 mlir::Block *entryBB = funcOp.addEntryBlock();
61
63 {
64 LexicalScope lexScope(*this, fusedLoc, entryBB);
65 startFunction(GlobalDecl(), getContext().VoidTy, funcOp, funcType, args,
66 loc, bodyRange.getBegin());
67 if (mlir::failed(emitFunctionBody(body)))
68 return;
69 if (mlir::failed(funcOp.verifyBody()))
70 return;
72 }
73
75}
76
77void CIRGenModule::emitSYCLKernelCaller(const FunctionDecl *kernelEntryPointFn,
78 ASTContext &ctx) {
79 assert(ctx.getLangOpts().SYCLIsDevice &&
80 "SYCL kernel caller offload entry point functions can only be emitted"
81 " during device compilation");
82
83 const auto *kernelEntryPointAttr =
84 kernelEntryPointFn->getAttr<SYCLKernelEntryPointAttr>();
85 assert(kernelEntryPointAttr && "Missing sycl_kernel_entry_point attribute");
86 assert(!kernelEntryPointAttr->isInvalidAttr() &&
87 "sycl_kernel_entry_point attribute is invalid");
88
89 // Find the SYCLKernelCallStmt.
90 SYCLKernelCallStmt *kernelCallStmt =
91 cast<SYCLKernelCallStmt>(kernelEntryPointFn->getBody());
92
93 // Retrieve the SYCL kernel caller parameters from the OutlinedFunctionDecl.
94 FunctionArgList args;
95 const OutlinedFunctionDecl *outlinedFnDecl =
96 kernelCallStmt->getOutlinedFunctionDecl();
97 args.append(outlinedFnDecl->param_begin(), outlinedFnDecl->param_end());
98
99 // Compute the function info and CIR function type.
100 const CIRGenFunctionInfo &fnInfo =
102 cir::FuncType funcType = getTypes().getFunctionType(fnInfo);
103
104 // Retrieve the generated name for the SYCL kernel caller function.
105 CanQualType kernelNameType =
106 ctx.getCanonicalType(kernelEntryPointAttr->getKernelName());
107 const SYCLKernelInfo &kernelInfo = ctx.getSYCLKernelInfo(kernelNameType);
108
109 // Synthesized from the OutlinedFunctionDecl, not a FunctionDecl, so create
110 // the function directly with a null FunctionDecl (mirrors classic CodeGen's
111 // llvm::Function::Create).
112 cir::FuncOp funcOp = createCIRFunction(
113 getLoc(kernelEntryPointFn->getSourceRange()), kernelInfo.GetKernelName(),
114 funcType, /*funcDecl=*/nullptr);
115 funcOp.setLinkage(cir::GlobalLinkageKind::ExternalLinkage);
116
117 // Emit as a device kernel (e.g. spir_kernel). Classic CodeGen derives this
118 // from CC_DeviceKernel via SetLLVMFunctionAttributes; CIR does not yet route
119 // opFuncCallingConv onto the FuncOp, so set it from the target hook.
120 funcOp.setCallingConv(getTargetCIRGenInfo().getDeviceKernelCallingConv());
121
122 // Route through the shared attribute path so generic function attributes
123 // (e.g. convergent) are applied, matching classic CodeGen's
124 // SetLLVMFunctionAttributes. There is no FunctionDecl, so pass an empty
125 // GlobalDecl.
126 setCIRFunctionAttributes(GlobalDecl(), fnInfo, funcOp, /*isThunk=*/false);
127
128 // TODO: attributes applied by classic CodeGen not yet handled in CIR:
129 // SetSYCLKernelAttributes (norecurse, mustprogress), addSYCLModuleIdAttr.
131
132 // Emit the SYCL kernel caller function.
133 CIRGenFunction cgf(*this, builder);
134 llvm::SaveAndRestore<CIRGenFunction *> savedCGF(curCGF, &cgf);
135 {
136 mlir::OpBuilder::InsertionGuard guard(builder);
137 cgf.emitSYCLKernelCaller(outlinedFnDecl, funcOp, funcType, args);
138 }
139
140 setDSOLocal(static_cast<mlir::Operation *>(funcOp));
141
142 setNonAliasAttributes(GlobalDecl(), funcOp);
143 // CIR's setter takes a FunctionDecl; nullptr skips OutlinedFunctionDecl-
144 // derived attributes (e.g. inline hints), not yet handled.
146 setCIRFunctionAttributesForDefinition(/*fd=*/nullptr, funcOp);
147}
Defines the clang::ASTContext interface.
This file declares types used to describe SYCL kernels.
This file defines SYCL AST classes used to represent calls to SYCL kernels.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:239
static CanQualType getCanonicalType(QualType T)
Return the canonical (structural) type corresponding to the specified potentially non-canonical type ...
const LangOptions & getLangOpts() const
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...
clang::GlobalDecl curGD
The GlobalDecl for the current function being compiled or the global variable currently being initial...
const clang::LangOptions & getLangOpts() const
mlir::Location getLoc(clang::SourceLocation srcLoc)
Helpers to convert Clang's SourceLocation to a MLIR Location.
llvm::ScopedHashTableScope< const clang::Decl *, mlir::Value > SymTableScopeTy
void finishFunction(SourceLocation endLoc)
mlir::LogicalResult emitFunctionBody(const clang::Stmt *body)
void startFunction(clang::GlobalDecl gd, clang::QualType returnType, cir::FuncOp fn, cir::FuncType funcType, FunctionArgList args, clang::SourceLocation loc, clang::SourceLocation startLoc)
Emit code for the start of a function.
static void eraseEmptyAndUnusedBlocks(cir::FuncOp func)
Remove leftover empty and unreachable blocks from an emitted function.
clang::ASTContext & getContext() const
void emitSYCLKernelCaller(const clang::OutlinedFunctionDecl *outlinedFnDecl, cir::FuncOp funcOp, cir::FuncType funcType, FunctionArgList &args)
mlir::LogicalResult emitStmt(const clang::Stmt *s, bool useCurrentScope, llvm::ArrayRef< const Attr * > attrs={})
mlir::LogicalResult emitSYCLKernelCallStmt(const SYCLKernelCallStmt &s)
void setDSOLocal(mlir::Operation *op) const
void setCIRFunctionAttributes(GlobalDecl gd, const CIRGenFunctionInfo &info, cir::FuncOp func, bool isThunk)
Set the CIR function attributes (Sext, zext, etc).
cir::FuncOp createCIRFunction(mlir::Location loc, llvm::StringRef name, cir::FuncType funcType, const clang::FunctionDecl *funcDecl)
const TargetCIRGenInfo & getTargetCIRGenInfo()
mlir::Location getLoc(clang::SourceLocation cLoc)
Helpers to convert the presumed location of Clang's SourceLocation to an MLIR Location.
void emitSYCLKernelCaller(const clang::FunctionDecl *kernelEntryPointFn, clang::ASTContext &ctx)
Emit the SYCL kernel caller offload entry point function generated for a function declared with the s...
void setCIRFunctionAttributesForDefinition(const clang::FunctionDecl *fd, cir::FuncOp f)
Set extra attributes (inline, etc.) for a function.
cir::FuncType getFunctionType(const CIRGenFunctionInfo &info)
Get the CIR function type for.
const CIRGenFunctionInfo & arrangeDeviceKernelCallerDeclaration(clang::QualType resultType, const FunctionArgList &args)
Arrange the function info for a device kernel caller entry point (e.g.
Type for representing both the decl and type of parameters to a function.
Definition CIRGenCall.h:193
T * getAttr() const
Definition DeclBase.h:581
SourceLocation getLocation() const
Definition DeclBase.h:447
Represents a function declaration or definition.
Definition Decl.h:2059
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
Definition Decl.cpp:3268
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
Definition Decl.cpp:4610
GlobalDecl - represents a global declaration.
Definition GlobalDecl.h:60
Represents a partial function definition.
Definition Decl.h:5014
parameter_const_iterator param_end() const
Definition Decl.h:5062
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:5744
parameter_const_iterator param_begin() const
Definition Decl.h:5061
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
Encodes a location in the source.
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
Stmt - This represents one statement.
Definition Stmt.h:85
SourceLocation getEndLoc() const LLVM_READONLY
Definition Stmt.cpp:367
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
Definition Stmt.cpp:343
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
static bool opFuncExtraAttrs()
static bool setLLVMFunctionFEnvAttributes()
Represents a scope, including function bodies, compound statements, and the substatements of if/while...