clang  16.0.0git
CGOpenCLRuntime.cpp
Go to the documentation of this file.
1 //===----- CGOpenCLRuntime.cpp - Interface to OpenCL Runtimes -------------===//
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 provides an abstract class for OpenCL code generation. Concrete
10 // subclasses of this implement code generation for specific OpenCL
11 // runtime libraries.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #include "CGOpenCLRuntime.h"
16 #include "CodeGenFunction.h"
17 #include "TargetInfo.h"
19 #include "llvm/IR/DerivedTypes.h"
20 #include "llvm/IR/GlobalValue.h"
21 #include <assert.h>
22 
23 using namespace clang;
24 using namespace CodeGen;
25 
27 
29  const VarDecl &D) {
31 }
32 
34  assert(T->isOpenCLSpecificType() &&
35  "Not an OpenCL specific type!");
36 
37  switch (cast<BuiltinType>(T)->getKind()) {
38  default:
39  llvm_unreachable("Unexpected opencl builtin type!");
40  return nullptr;
41 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
42  case BuiltinType::Id: \
43  return getPointerType(T, "opencl." #ImgType "_" #Suffix "_t");
44 #include "clang/Basic/OpenCLImageTypes.def"
45  case BuiltinType::OCLSampler:
46  return getSamplerType(T);
47  case BuiltinType::OCLEvent:
48  return getPointerType(T, "opencl.event_t");
49  case BuiltinType::OCLClkEvent:
50  return getPointerType(T, "opencl.clk_event_t");
51  case BuiltinType::OCLQueue:
52  return getPointerType(T, "opencl.queue_t");
53  case BuiltinType::OCLReserveID:
54  return getPointerType(T, "opencl.reserve_id_t");
55 #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
56  case BuiltinType::Id: \
57  return getPointerType(T, "opencl." #ExtType);
58 #include "clang/Basic/OpenCLExtensionTypes.def"
59  }
60 }
61 
62 llvm::PointerType *CGOpenCLRuntime::getPointerType(const Type *T,
63  StringRef Name) {
64  auto I = CachedTys.find(Name);
65  if (I != CachedTys.end())
66  return I->second;
67 
68  llvm::LLVMContext &Ctx = CGM.getLLVMContext();
69  uint32_t AddrSpc = CGM.getContext().getTargetAddressSpace(
71  auto *PTy =
72  llvm::PointerType::get(llvm::StructType::create(Ctx, Name), AddrSpc);
73  CachedTys[Name] = PTy;
74  return PTy;
75 }
76 
77 llvm::Type *CGOpenCLRuntime::getPipeType(const PipeType *T) {
78  if (T->isReadOnly())
79  return getPipeType(T, "opencl.pipe_ro_t", PipeROTy);
80  else
81  return getPipeType(T, "opencl.pipe_wo_t", PipeWOTy);
82 }
83 
84 llvm::Type *CGOpenCLRuntime::getPipeType(const PipeType *T, StringRef Name,
85  llvm::Type *&PipeTy) {
86  if (!PipeTy)
87  PipeTy = llvm::PointerType::get(llvm::StructType::create(
88  CGM.getLLVMContext(), Name),
91  return PipeTy;
92 }
93 
94 llvm::PointerType *CGOpenCLRuntime::getSamplerType(const Type *T) {
95  if (!SamplerTy)
96  SamplerTy = llvm::PointerType::get(llvm::StructType::create(
97  CGM.getLLVMContext(), "opencl.sampler_t"),
100  return SamplerTy;
101 }
102 
103 llvm::Value *CGOpenCLRuntime::getPipeElemSize(const Expr *PipeArg) {
104  const PipeType *PipeTy = PipeArg->getType()->castAs<PipeType>();
105  // The type of the last (implicit) argument to be passed.
106  llvm::Type *Int32Ty = llvm::IntegerType::getInt32Ty(CGM.getLLVMContext());
107  unsigned TypeSize = CGM.getContext()
109  .getQuantity();
110  return llvm::ConstantInt::get(Int32Ty, TypeSize, false);
111 }
112 
113 llvm::Value *CGOpenCLRuntime::getPipeElemAlign(const Expr *PipeArg) {
114  const PipeType *PipeTy = PipeArg->getType()->castAs<PipeType>();
115  // The type of the last (implicit) argument to be passed.
116  llvm::Type *Int32Ty = llvm::IntegerType::getInt32Ty(CGM.getLLVMContext());
117  unsigned TypeSize = CGM.getContext()
119  .getQuantity();
120  return llvm::ConstantInt::get(Int32Ty, TypeSize, false);
121 }
122 
124  assert(CGM.getLangOpts().OpenCL);
125  return llvm::IntegerType::getInt8PtrTy(
128 }
129 
130 // Get the block literal from an expression derived from the block expression.
131 // OpenCL v2.0 s6.12.5:
132 // Block variable declarations are implicitly qualified with const. Therefore
133 // all block variables must be initialized at declaration time and may not be
134 // reassigned.
135 static const BlockExpr *getBlockExpr(const Expr *E) {
136  const Expr *Prev = nullptr; // to make sure we do not stuck in infinite loop.
137  while(!isa<BlockExpr>(E) && E != Prev) {
138  Prev = E;
139  E = E->IgnoreCasts();
140  if (auto DR = dyn_cast<DeclRefExpr>(E)) {
141  E = cast<VarDecl>(DR->getDecl())->getInit();
142  }
143  }
144  return cast<BlockExpr>(E);
145 }
146 
147 /// Record emitted llvm invoke function and llvm block literal for the
148 /// corresponding block expression.
150  llvm::Function *InvokeF,
151  llvm::Value *Block, llvm::Type *BlockTy) {
152  assert(EnqueuedBlockMap.find(E) == EnqueuedBlockMap.end() &&
153  "Block expression emitted twice");
154  assert(isa<llvm::Function>(InvokeF) && "Invalid invoke function");
155  assert(Block->getType()->isPointerTy() && "Invalid block literal type");
156  EnqueuedBlockMap[E].InvokeFunc = InvokeF;
157  EnqueuedBlockMap[E].BlockArg = Block;
158  EnqueuedBlockMap[E].BlockTy = BlockTy;
159  EnqueuedBlockMap[E].Kernel = nullptr;
160 }
161 
162 llvm::Function *CGOpenCLRuntime::getInvokeFunction(const Expr *E) {
163  return EnqueuedBlockMap[getBlockExpr(E)].InvokeFunc;
164 }
165 
168  CGF.EmitScalarExpr(E);
169 
170  // The block literal may be assigned to a const variable. Chasing down
171  // to get the block literal.
172  const BlockExpr *Block = getBlockExpr(E);
173 
174  assert(EnqueuedBlockMap.find(Block) != EnqueuedBlockMap.end() &&
175  "Block expression not emitted");
176 
177  // Do not emit the block wrapper again if it has been emitted.
179  return EnqueuedBlockMap[Block];
180  }
181 
183  CGF, EnqueuedBlockMap[Block].InvokeFunc, EnqueuedBlockMap[Block].BlockTy);
184 
185  // The common part of the post-processing of the kernel goes here.
186  F->addFnAttr(llvm::Attribute::NoUnwind);
187  F->setCallingConv(
189  EnqueuedBlockMap[Block].Kernel = F;
190  return EnqueuedBlockMap[Block];
191 }
clang::InternalLinkage
@ InternalLinkage
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
Definition: Linkage.h:31
clang::ASTContext::getTypeSizeInChars
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
Definition: ASTContext.cpp:2515
clang::PipeType::isReadOnly
bool isReadOnly() const
Definition: Type.h:6500
clang::Type::isOpenCLSpecificType
bool isOpenCLSpecificType() const
Definition: Type.h:7132
clang::CodeGen::CGOpenCLRuntime::EnqueuedBlockMap
llvm::DenseMap< const Expr *, EnqueuedBlockInfo > EnqueuedBlockMap
Maps block expression to block information.
Definition: CGOpenCLRuntime.h:52
clang::CodeGen::CGOpenCLRuntime::getSamplerType
llvm::PointerType * getSamplerType(const Type *T)
Definition: CGOpenCLRuntime.cpp:94
CodeGenFunction.h
clang::PipeType::getElementType
QualType getElementType() const
Definition: Type.h:6481
clang::CodeGen::CGOpenCLRuntime::emitOpenCLEnqueuedBlock
EnqueuedBlockInfo emitOpenCLEnqueuedBlock(CodeGenFunction &CGF, const Expr *E)
Definition: CGOpenCLRuntime.cpp:167
clang::CodeGen::CGOpenCLRuntime::getPipeElemSize
virtual llvm::Value * getPipeElemSize(const Expr *PipeArg)
Definition: CGOpenCLRuntime.cpp:103
clang::CodeGen::CodeGenModule::getContext
ASTContext & getContext() const
Definition: CodeGenModule.h:722
clang::PipeType
PipeType - OpenCL20.
Definition: Type.h:6470
clang::CodeGen::TargetCodeGenInfo::createEnqueuedBlockKernel
virtual llvm::Function * createEnqueuedBlockKernel(CodeGenFunction &CGF, llvm::Function *BlockInvokeFunc, llvm::Type *BlockTy) const
Create an OpenCL kernel for an enqueued block.
Definition: TargetInfo.cpp:12311
TargetInfo.h
clang::CodeGen::CodeGenModule::getLangOpts
const LangOptions & getLangOpts() const
Definition: CodeGenModule.h:723
clang::Type
The base class of the type hierarchy.
Definition: Type.h:1565
clang::CC_OpenCLKernel
@ CC_OpenCLKernel
Definition: Specifiers.h:280
clang::CodeGen::CGOpenCLRuntime::PipeWOTy
llvm::Type * PipeWOTy
Definition: CGOpenCLRuntime.h:40
clang::ASTContext::getTypeAlignInChars
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
Definition: ASTContext.cpp:2524
clang::CodeGen::CGOpenCLRuntime::PipeROTy
llvm::Type * PipeROTy
Definition: CGOpenCLRuntime.h:39
clang::CodeGen::CGOpenCLRuntime::SamplerTy
llvm::PointerType * SamplerTy
Definition: CGOpenCLRuntime.h:41
clang::CodeGen::CGOpenCLRuntime::getPipeElemAlign
virtual llvm::Value * getPipeElemAlign(const Expr *PipeArg)
Definition: CGOpenCLRuntime.cpp:113
clang::VarDecl
Represents a variable declaration or definition.
Definition: Decl.h:906
clang::KernelReferenceKind::Kernel
@ Kernel
clang::CodeGen::CodeGenTypes::ClangCallConvToLLVMCallConv
unsigned ClangCallConvToLLVMCallConv(CallingConv CC)
Convert clang calling convention to LLVM callilng convention.
Definition: CGCall.cpp:48
clang::CodeGen::CGOpenCLRuntime::EmitWorkGroupLocalVarDecl
virtual void EmitWorkGroupLocalVarDecl(CodeGenFunction &CGF, const VarDecl &D)
Emit the IR required for a work-group-local variable declaration, and add an entry to CGF's LocalDecl...
Definition: CGOpenCLRuntime.cpp:28
getKind
static Decl::Kind getKind(const Decl *D)
Definition: DeclBase.cpp:1024
clang::ASTContext::getTargetAddressSpace
unsigned getTargetAddressSpace(LangAS AS) const
Definition: ASTContext.cpp:12230
clang::Type::castAs
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:7453
clang::CodeGen::CGOpenCLRuntime::recordBlockInfo
void recordBlockInfo(const BlockExpr *E, llvm::Function *InvokeF, llvm::Value *Block, llvm::Type *BlockTy)
Record invoke function and block literal emitted during normal codegen for a block expression.
Definition: CGOpenCLRuntime.cpp:149
clang::serialized_diags::create
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
Definition: SerializedDiagnosticPrinter.cpp:301
clang::CodeGen::CodeGenFunction::getTargetHooks
const TargetCodeGenInfo & getTargetHooks() const
Definition: CodeGenFunction.h:2028
clang::CodeGen::CGOpenCLRuntime::getInvokeFunction
llvm::Function * getInvokeFunction(const Expr *E)
Definition: CGOpenCLRuntime.cpp:162
clang::CodeGen::CodeGenFunction
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
Definition: CodeGenFunction.h:231
clang::ASTContext::getOpenCLTypeAddrSpace
LangAS getOpenCLTypeAddrSpace(const Type *T) const
Get address space for OpenCL type.
Definition: ASTContext.cpp:7505
clang::BlockExpr
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition: Expr.h:5975
clang::CodeGen::CGOpenCLRuntime::EnqueuedBlockInfo
Structure for enqueued block information.
Definition: CGOpenCLRuntime.h:45
clang::CodeGen::CodeGenFunction::getTypes
CodeGenTypes & getTypes() const
Definition: CodeGenFunction.h:1983
getBlockExpr
static const BlockExpr * getBlockExpr(const Expr *E)
Definition: CGOpenCLRuntime.cpp:135
clang::CodeGen::CodeGenFunction::EmitScalarExpr
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type,...
Definition: CGExprScalar.cpp:5041
clang::CodeGen::CGOpenCLRuntime::~CGOpenCLRuntime
virtual ~CGOpenCLRuntime()
Definition: CGOpenCLRuntime.cpp:26
clang::CodeGen::CGOpenCLRuntime::convertOpenCLSpecificType
virtual llvm::Type * convertOpenCLSpecificType(const Type *T)
Definition: CGOpenCLRuntime.cpp:33
clang::CodeGen::CGOpenCLRuntime::getPipeType
virtual llvm::Type * getPipeType(const PipeType *T, StringRef Name, llvm::Type *&PipeTy)
Definition: CGOpenCLRuntime.cpp:84
clang
Definition: CalledOnceCheck.h:17
CGOpenCLRuntime.h
clang::DeclaratorContext::Block
@ Block
clang::Expr::getType
QualType getType() const
Definition: Expr.h:141
clang::CodeGen::CGOpenCLRuntime::CachedTys
llvm::StringMap< llvm::PointerType * > CachedTys
Definition: CGOpenCLRuntime.h:42
clang::CodeGen::CodeGenFunction::EmitStaticVarDecl
void EmitStaticVarDecl(const VarDecl &D, llvm::GlobalValue::LinkageTypes Linkage)
Definition: CGDecl.cpp:411
clang::CodeGen::CGOpenCLRuntime::getPointerType
llvm::PointerType * getPointerType(const Type *T, StringRef Name)
Definition: CGOpenCLRuntime.cpp:62
clang::Expr::IgnoreCasts
Expr * IgnoreCasts() LLVM_READONLY
Skip past any casts which might surround this expression until reaching a fixed point.
Definition: Expr.cpp:3019
clang::CodeGen::CGOpenCLRuntime::getGenericVoidPointerType
llvm::PointerType * getGenericVoidPointerType()
Definition: CGOpenCLRuntime.cpp:123
clang::Expr
This represents one expression.
Definition: Expr.h:109
clang::LangAS::opencl_generic
@ opencl_generic
clang::CodeGen::CodeGenModule::getLLVMContext
llvm::LLVMContext & getLLVMContext()
Definition: CodeGenModule.h:743
clang::CodeGen::CGOpenCLRuntime::CGM
CodeGenModule & CGM
Definition: CGOpenCLRuntime.h:38
clang::CharUnits::getQuantity
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Definition: CharUnits.h:179
ConstantInitBuilder.h