clang  8.0.0svn
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"
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 
28 
30  const VarDecl &D) {
32 }
33 
35  assert(T->isOpenCLSpecificType() &&
36  "Not an OpenCL specific type!");
37 
38  llvm::LLVMContext& Ctx = CGM.getLLVMContext();
39  uint32_t AddrSpc = CGM.getContext().getTargetAddressSpace(
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  }
66 }
67 
69  if (T->isReadOnly())
70  return getPipeType(T, "opencl.pipe_ro_t", PipeROTy);
71  else
72  return getPipeType(T, "opencl.pipe_wo_t", PipeWOTy);
73 }
74 
76  llvm::Type *&PipeTy) {
77  if (!PipeTy)
78  PipeTy = llvm::PointerType::get(llvm::StructType::create(
79  CGM.getLLVMContext(), Name),
82  return PipeTy;
83 }
84 
85 llvm::PointerType *CGOpenCLRuntime::getSamplerType(const Type *T) {
86  if (!SamplerTy)
87  SamplerTy = llvm::PointerType::get(llvm::StructType::create(
88  CGM.getLLVMContext(), "opencl.sampler_t"),
91  return SamplerTy;
92 }
93 
95  const PipeType *PipeTy = PipeArg->getType()->getAs<PipeType>();
96  // The type of the last (implicit) argument to be passed.
97  llvm::Type *Int32Ty = llvm::IntegerType::getInt32Ty(CGM.getLLVMContext());
98  unsigned TypeSize = CGM.getContext()
100  .getQuantity();
101  return llvm::ConstantInt::get(Int32Ty, TypeSize, false);
102 }
103 
105  const PipeType *PipeTy = PipeArg->getType()->getAs<PipeType>();
106  // The type of the last (implicit) argument to be passed.
107  llvm::Type *Int32Ty = llvm::IntegerType::getInt32Ty(CGM.getLLVMContext());
108  unsigned TypeSize = CGM.getContext()
110  .getQuantity();
111  return llvm::ConstantInt::get(Int32Ty, TypeSize, false);
112 }
113 
115  assert(CGM.getLangOpts().OpenCL);
116  return llvm::IntegerType::getInt8PtrTy(
119 }
120 
121 // Get the block literal from an expression derived from the block expression.
122 // OpenCL v2.0 s6.12.5:
123 // Block variable declarations are implicitly qualified with const. Therefore
124 // all block variables must be initialized at declaration time and may not be
125 // reassigned.
126 static const BlockExpr *getBlockExpr(const Expr *E) {
127  if (auto Cast = dyn_cast<CastExpr>(E)) {
128  E = Cast->getSubExpr();
129  }
130  if (auto DR = dyn_cast<DeclRefExpr>(E)) {
131  E = cast<VarDecl>(DR->getDecl())->getInit();
132  }
133  E = E->IgnoreImplicit();
134  if (auto Cast = dyn_cast<CastExpr>(E)) {
135  E = Cast->getSubExpr();
136  }
137  return cast<BlockExpr>(E);
138 }
139 
140 /// Record emitted llvm invoke function and llvm block literal for the
141 /// corresponding block expression.
143  llvm::Function *InvokeF,
144  llvm::Value *Block) {
145  assert(EnqueuedBlockMap.find(E) == EnqueuedBlockMap.end() &&
146  "Block expression emitted twice");
147  assert(isa<llvm::Function>(InvokeF) && "Invalid invoke function");
148  assert(Block->getType()->isPointerTy() && "Invalid block literal type");
149  EnqueuedBlockMap[E].InvokeFunc = InvokeF;
150  EnqueuedBlockMap[E].BlockArg = Block;
151  EnqueuedBlockMap[E].Kernel = nullptr;
152 }
153 
154 llvm::Function *CGOpenCLRuntime::getInvokeFunction(const Expr *E) {
155  return EnqueuedBlockMap[getBlockExpr(E)].InvokeFunc;
156 }
157 
160  CGF.EmitScalarExpr(E);
161 
162  const BlockExpr *Block = getBlockExpr(E);
163  assert(EnqueuedBlockMap.find(Block) != EnqueuedBlockMap.end() &&
164  "Block expression not emitted");
165 
166  // Do not emit the block wrapper again if it has been emitted.
167  if (EnqueuedBlockMap[Block].Kernel) {
168  return EnqueuedBlockMap[Block];
169  }
170 
172  CGF, EnqueuedBlockMap[Block].InvokeFunc,
173  EnqueuedBlockMap[Block].BlockArg->stripPointerCasts());
174 
175  // The common part of the post-processing of the kernel goes here.
176  F->addFnAttr(llvm::Attribute::NoUnwind);
177  F->setCallingConv(
179  EnqueuedBlockMap[Block].Kernel = F;
180  return EnqueuedBlockMap[Block];
181 }
void EmitStaticVarDecl(const VarDecl &D, llvm::GlobalValue::LinkageTypes Linkage)
Definition: CGDecl.cpp:377
QualType getElementType() const
Definition: Type.h:5897
llvm::LLVMContext & getLLVMContext()
The base class of the type hierarchy.
Definition: Type.h:1415
EnqueuedBlockInfo emitOpenCLEnqueuedBlock(CodeGenFunction &CGF, const Expr *E)
virtual llvm::Value * getPipeElemAlign(const Expr *PipeArg)
Represents a variable declaration or definition.
Definition: Decl.h:812
const T * getAs() const
Member-template getAs<specific type>&#39;.
Definition: Type.h:6590
Expr * IgnoreImplicit() LLVM_READONLY
IgnoreImplicit - Skip past any implicit AST nodes which might surround this expression.
Definition: Expr.h:740
PipeType - OpenCL20.
Definition: Type.h:5883
unsigned ClangCallConvToLLVMCallConv(CallingConv CC)
Convert clang calling convention to LLVM callilng convention.
Definition: CGCall.cpp:46
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
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...
virtual llvm::Type * getPipeType(const PipeType *T, StringRef Name, llvm::Type *&PipeTy)
llvm::PointerType * getSamplerType(const Type *T)
virtual llvm::Type * convertOpenCLSpecificType(const Type *T)
This represents one expression.
Definition: Expr.h:105
llvm::DenseMap< const Expr *, EnqueuedBlockInfo > EnqueuedBlockMap
Maps block expression to block information.
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...
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition: Expr.h:4974
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
QualType getType() const
Definition: Expr.h:127
const LangOptions & getLangOpts() const
ASTContext & getContext() const
virtual llvm::Value * getPipeElemSize(const Expr *PipeArg)
llvm::Function * getInvokeFunction(const Expr *E)
LangAS getOpenCLTypeAddrSpace(const Type *T) const
Get address space for OpenCL type.
static const BlockExpr * getBlockExpr(const Expr *E)
The l-value was considered opaque, so the alignment was determined from a type.
const TargetCodeGenInfo & getTargetHooks() const
llvm::Value * EmitScalarExpr(const Expr *E, bool IgnoreResultAssign=false)
EmitScalarExpr - Emit the computation of the specified expression of LLVM scalar type, returning the result.
Dataflow Directional Tag Classes.
Structure for enqueued block information.
virtual llvm::Function * createEnqueuedBlockKernel(CodeGenFunction &CGF, llvm::Function *BlockInvokeFunc, llvm::Value *BlockLiteral) const
Create an OpenCL kernel for an enqueued block.
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
CodeGenTypes & getTypes() const
Internal linkage, which indicates that the entity can be referred to from within the translation unit...
Definition: Linkage.h:32
bool isReadOnly() const
Definition: Type.h:5916
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
llvm::PointerType * getGenericVoidPointerType()
bool isOpenCLSpecificType() const
Definition: Type.h:6362
unsigned getTargetAddressSpace(QualType T) const
Definition: ASTContext.h:2505