clang 8.0.0

CGOpenCLRuntime.cpp
Go to the documentation of this file.
1 //===----- CGOpenCLRuntime.cpp - Interface to OpenCL Runtimes -------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This provides an abstract class for OpenCL code generation. Concrete
11 // subclasses of this implement code generation for specific OpenCL
12 // runtime libraries.
13 //
14 //===----------------------------------------------------------------------===//
15
16 #include "CGOpenCLRuntime.h"
17 #include "CodeGenFunction.h"
18 #include "TargetInfo.h"
19 #include "clang/CodeGen/ConstantInitBuilder.h"
20 #include "llvm/IR/DerivedTypes.h"
21 #include "llvm/IR/GlobalValue.h"
22 #include <assert.h>
23
24 using namespace clang;
25 using namespace CodeGen;
26
27 CGOpenCLRuntime::~CGOpenCLRuntime() {}
28
29 void CGOpenCLRuntime::EmitWorkGroupLocalVarDecl(CodeGenFunction &CGF,
30 const VarDecl &D) {
31 return CGF.EmitStaticVarDecl(D, llvm::GlobalValue::InternalLinkage);
32 }
33
34 llvm::Type *CGOpenCLRuntime::convertOpenCLSpecificType(const Type *T) {
35 assert(T->isOpenCLSpecificType() &&
36 "Not an OpenCL specific type!");
37
38 llvm::LLVMContext& Ctx = CGM.getLLVMContext();
39 uint32_t AddrSpc = CGM.getContext().getTargetAddressSpace(
40 CGM.getContext().getOpenCLTypeAddrSpace(T));
41 switch (cast<BuiltinType>(T)->getKind()) {
42 default:
43 llvm_unreachable("Unexpected opencl builtin type!");
44 return nullptr;
45 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
46 case BuiltinType::Id: \
47 return llvm::PointerType::get( \
48 llvm::StructType::create(Ctx, "opencl." #ImgType "_" #Suffix "_t"), \
49 AddrSpc);
50 #include "clang/Basic/OpenCLImageTypes.def"
51 case BuiltinType::OCLSampler:
52 return getSamplerType(T);
53 case BuiltinType::OCLEvent:
54 return llvm::PointerType::get(
55 llvm::StructType::create(Ctx, "opencl.event_t"), AddrSpc);
56 case BuiltinType::OCLClkEvent:
57 return llvm::PointerType::get(
58 llvm::StructType::create(Ctx, "opencl.clk_event_t"), AddrSpc);
59 case BuiltinType::OCLQueue:
60 return llvm::PointerType::get(
61 llvm::StructType::create(Ctx, "opencl.queue_t"), AddrSpc);
62 case BuiltinType::OCLReserveID:
63 return llvm::PointerType::get(
64 llvm::StructType::create(Ctx, "opencl.reserve_id_t"), AddrSpc);
65 #define EXT_OPAQUE_TYPE(ExtType, Id, Ext) \
66 case BuiltinType::Id: \
67 return llvm::PointerType::get( \
68 llvm::StructType::create(Ctx, "opencl." #ExtType), AddrSpc);
69 #include "clang/Basic/OpenCLExtensionTypes.def"
70 }
71 }
72
73 llvm::Type *CGOpenCLRuntime::getPipeType(const PipeType *T) {
74 if (T->isReadOnly())
75 return getPipeType(T, "opencl.pipe_ro_t", PipeROTy);
76 else
77 return getPipeType(T, "opencl.pipe_wo_t", PipeWOTy);
78 }
79
80 llvm::Type *CGOpenCLRuntime::getPipeType(const PipeType *T, StringRef Name,
81 llvm::Type *&PipeTy) {
82 if (!PipeTy)
83 PipeTy = llvm::PointerType::get(llvm::StructType::create(
84 CGM.getLLVMContext(), Name),
85 CGM.getContext().getTargetAddressSpace(
86 CGM.getContext().getOpenCLTypeAddrSpace(T)));
87 return PipeTy;
88 }
89
90 llvm::PointerType *CGOpenCLRuntime::getSamplerType(const Type *T) {
91 if (!SamplerTy)
92 SamplerTy = llvm::PointerType::get(llvm::StructType::create(
93 CGM.getLLVMContext(), "opencl.sampler_t"),
94 CGM.getContext().getTargetAddressSpace(
95 CGM.getContext().getOpenCLTypeAddrSpace(T)));
96 return SamplerTy;
97 }
98
99 llvm::Value *CGOpenCLRuntime::getPipeElemSize(const Expr *PipeArg) {
100 const PipeType *PipeTy = PipeArg->getType()->getAs<PipeType>();
101 // The type of the last (implicit) argument to be passed.
102 llvm::Type *Int32Ty = llvm::IntegerType::getInt32Ty(CGM.getLLVMContext());
103 unsigned TypeSize = CGM.getContext()
104 .getTypeSizeInChars(PipeTy->getElementType())
105 .getQuantity();
106 return llvm::ConstantInt::get(Int32Ty, TypeSize, false);
107 }
108
109 llvm::Value *CGOpenCLRuntime::getPipeElemAlign(const Expr *PipeArg) {
110 const PipeType *PipeTy = PipeArg->getType()->getAs<PipeType>();
111 // The type of the last (implicit) argument to be passed.
112 llvm::Type *Int32Ty = llvm::IntegerType::getInt32Ty(CGM.getLLVMContext());
113 unsigned TypeSize = CGM.getContext()
114 .getTypeAlignInChars(PipeTy->getElementType())
115 .getQuantity();
116 return llvm::ConstantInt::get(Int32Ty, TypeSize, false);
117 }
118
119 llvm::PointerType *CGOpenCLRuntime::getGenericVoidPointerType() {
120 assert(CGM.getLangOpts().OpenCL);
121 return llvm::IntegerType::getInt8PtrTy(
122 CGM.getLLVMContext(),
123 CGM.getContext().getTargetAddressSpace(LangAS::opencl_generic));
124 }
125
126 /// Record emitted llvm invoke function and llvm block literal for the
127 /// corresponding block expression.
128 void CGOpenCLRuntime::recordBlockInfo(const BlockExpr *E,
129 llvm::Function *InvokeF,
130 llvm::Value *Block) {
131 assert(EnqueuedBlockMap.find(E) == EnqueuedBlockMap.end() &&
132 "Block expression emitted twice");
133 assert(isa<llvm::Function>(InvokeF) && "Invalid invoke function");
134 assert(Block->getType()->isPointerTy() && "Invalid block literal type");
135 EnqueuedBlockMap[E].InvokeFunc = InvokeF;
136 EnqueuedBlockMap[E].BlockArg = Block;
137 EnqueuedBlockMap[E].Kernel = nullptr;
138 }
139
140 CGOpenCLRuntime::EnqueuedBlockInfo
141 CGOpenCLRuntime::emitOpenCLEnqueuedBlock(CodeGenFunction &CGF, const Expr *E) {
142 CGF.EmitScalarExpr(E);
143
144 // The block literal may be assigned to a const variable. Chasing down
145 // to get the block literal.
146 if (auto DR = dyn_cast<DeclRefExpr>(E)) {
147 E = cast<VarDecl>(DR->getDecl())->getInit();
148 }
149 E = E->IgnoreImplicit();
150 if (auto Cast = dyn_cast<CastExpr>(E)) {
151 E = Cast->getSubExpr();
152 }
153 auto *Block = cast<BlockExpr>(E);
154
155 assert(EnqueuedBlockMap.find(Block) != EnqueuedBlockMap.end() &&
156 "Block expression not emitted");
157
158 // Do not emit the block wrapper again if it has been emitted.
159 if (EnqueuedBlockMap[Block].Kernel) {
160 return EnqueuedBlockMap[Block];
161 }
162
163 auto *F = CGF.getTargetHooks().createEnqueuedBlockKernel(
164 CGF, EnqueuedBlockMap[Block].InvokeFunc,
165 EnqueuedBlockMap[Block].BlockArg->stripPointerCasts());
166
167 // The common part of the post-processing of the kernel goes here.
168 F->addFnAttr(llvm::Attribute::NoUnwind);
169 F->setCallingConv(
170 CGF.getTypes().ClangCallConvToLLVMCallConv(CallingConv::CC_OpenCLKernel));
171 EnqueuedBlockMap[Block].Kernel = F;
172 return EnqueuedBlockMap[Block];
173 }
clang::CC_OpenCLKernel
Definition: Specifiers.h:250
clang::CodeGen::CodeGenFunction::EmitStaticVarDecl
void EmitStaticVarDecl(const VarDecl &D, llvm::GlobalValue::LinkageTypes Linkage)
Definition: CGDecl.cpp:378
clang::PipeType::getElementType
QualType getElementType() const
Definition: Type.h:6016
clang::CodeGen::CodeGenModule::getLLVMContext
llvm::LLVMContext & getLLVMContext()
Definition: CodeGenModule.h:670
clang::Type
The base class of the type hierarchy.
Definition: Type.h:1407
clang::CodeGen::CGOpenCLRuntime::emitOpenCLEnqueuedBlock
EnqueuedBlockInfo emitOpenCLEnqueuedBlock(CodeGenFunction &CGF, const Expr *E)
Definition: CGOpenCLRuntime.cpp:141
Value
Value
Definition: UninitializedValues.cpp:102
clang::CodeGen::CGOpenCLRuntime::getPipeElemAlign
virtual llvm::Value * getPipeElemAlign(const Expr *PipeArg)
Definition: CGOpenCLRuntime.cpp:109
clang::VarDecl
Represents a variable declaration or definition.
Definition: Decl.h:813
clang::Type::getAs
const T * getAs() const
Member-template getAs<specific type>&#39;.
Definition: Type.h:6748
clang::Expr::IgnoreImplicit
Expr * IgnoreImplicit() LLVM_READONLY
IgnoreImplicit - Skip past any implicit AST nodes which might surround this expression.
Definition: Expr.h:747
clang::CodeGen::CGOpenCLRuntime::PipeWOTy
llvm::Type * PipeWOTy
Definition: CGOpenCLRuntime.h:40
clang::PipeType
PipeType - OpenCL20.
Definition: Type.h:6002
clang::CodeGen::CodeGenTypes::ClangCallConvToLLVMCallConv
unsigned ClangCallConvToLLVMCallConv(CallingConv CC)
Convert clang calling convention to LLVM callilng convention.
Definition: CGCall.cpp:46
clang::CodeGen::CodeGenFunction
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
Definition: CodeGenFunction.h:227
clang::CodeGen::CGOpenCLRuntime::recordBlockInfo
void recordBlockInfo(const BlockExpr *E, llvm::Function *InvokeF, llvm::Value *Block)
Record invoke function and block literal emitted during normal codegen for a block expression...
Definition: CGOpenCLRuntime.cpp:128
clang::CodeGen::CGOpenCLRuntime::~CGOpenCLRuntime
virtual ~CGOpenCLRuntime()
Definition: CGOpenCLRuntime.cpp:27
clang::CodeGen::CGOpenCLRuntime::getPipeType
virtual llvm::Type * getPipeType(const PipeType *T, StringRef Name, llvm::Type *&PipeTy)
Definition: CGOpenCLRuntime.cpp:80
clang::CodeGen::CGOpenCLRuntime::getSamplerType
llvm::PointerType * getSamplerType(const Type *T)
Definition: CGOpenCLRuntime.cpp:90
clang::CodeGen::CGOpenCLRuntime::convertOpenCLSpecificType
virtual llvm::Type * convertOpenCLSpecificType(const Type *T)
Definition: CGOpenCLRuntime.cpp:34
clang::Expr
This represents one expression.
Definition: Expr.h:106
clang::CodeGen::CGOpenCLRuntime::EnqueuedBlockMap
llvm::DenseMap< const Expr *, EnqueuedBlockInfo > EnqueuedBlockMap
Maps block expression to block information.
Definition: CGOpenCLRuntime.h:50
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&#39;s LocalDecl...
Definition: CGOpenCLRuntime.cpp:29
clang::BlockExpr
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition: Expr.h:5177
clang::ASTContext::getTypeAlignInChars
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
Definition: ASTContext.cpp:2176
clang::CodeGen::CGOpenCLRuntime::PipeROTy
llvm::Type * PipeROTy
Definition: CGOpenCLRuntime.h:39
clang::Expr::getType
QualType getType() const
Definition: Expr.h:128
clang::CodeGen::CodeGenModule::getLangOpts
const LangOptions & getLangOpts() const
Definition: CodeGenModule.h:653
clang::CodeGen::CodeGenModule::getContext
ASTContext & getContext() const
Definition: CodeGenModule.h:652
clang::CodeGen::CGOpenCLRuntime::getPipeElemSize
virtual llvm::Value * getPipeElemSize(const Expr *PipeArg)
Definition: CGOpenCLRuntime.cpp:99
CodeGenFunction.h
clang::CodeGen::CGOpenCLRuntime::SamplerTy
llvm::PointerType * SamplerTy
Definition: CGOpenCLRuntime.h:41
clang::ASTContext::getOpenCLTypeAddrSpace
LangAS getOpenCLTypeAddrSpace(const Type *T) const
Get address space for OpenCL type.
Definition: ASTContext.cpp:6046
clang::CodeGen::AlignmentSource::Type
The l-value was considered opaque, so the alignment was determined from a type.
clang::LangAS::opencl_generic
TargetInfo.h
CGOpenCLRuntime.h
clang::CodeGen::CGOpenCLRuntime::CGM
CodeGenModule & CGM
Definition: CGOpenCLRuntime.h:38
clang::CodeGen::CodeGenFunction::getTargetHooks
const TargetCodeGenInfo & getTargetHooks() const
Definition: CodeGenFunction.h:1640
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, returning the result.
Definition: CGExprScalar.cpp:4290
clang
Dataflow Directional Tag Classes.
Definition: CFGReachabilityAnalysis.h:22
clang::CodeGen::CGOpenCLRuntime::EnqueuedBlockInfo
Structure for enqueued block information.
Definition: CGOpenCLRuntime.h:44
clang::CodeGen::TargetCodeGenInfo::createEnqueuedBlockKernel
virtual llvm::Function * createEnqueuedBlockKernel(CodeGenFunction &CGF, llvm::Function *BlockInvokeFunc, llvm::Value *BlockLiteral) const
Create an OpenCL kernel for an enqueued block.
Definition: TargetInfo.cpp:9427
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:297
clang::CodeGen::CodeGenFunction::getTypes
CodeGenTypes & getTypes() const
Definition: CodeGenFunction.h:1595
clang::InternalLinkage
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
Definition: Linkage.h:32
clang::PipeType::isReadOnly
bool isReadOnly() const
Definition: Type.h:6035
clang::ASTContext::getTypeSizeInChars
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
Definition: ASTContext.cpp:2167
ConstantInitBuilder.h
clang::CodeGen::CGOpenCLRuntime::getGenericVoidPointerType
llvm::PointerType * getGenericVoidPointerType()
Definition: CGOpenCLRuntime.cpp:119
clang::Type::isOpenCLSpecificType
bool isOpenCLSpecificType() const
Definition: Type.h:6502
clang::ASTContext::getTargetAddressSpace
unsigned getTargetAddressSpace(QualType T) const
Definition: ASTContext.h:2499