clang  20.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) {
30  return CGF.EmitStaticVarDecl(D, llvm::GlobalValue::InternalLinkage);
31 }
32 
34  assert(T->isOpenCLSpecificType() && "Not an OpenCL specific type!");
35 
36  // Check if the target has a specific translation for this type first.
37  if (llvm::Type *TransTy = CGM.getTargetCodeGenInfo().getOpenCLType(CGM, T))
38  return TransTy;
39 
40  if (CGM.getTriple().isNVPTX()) {
41  switch (cast<BuiltinType>(T)->getKind()) {
42  default:
43  break;
44 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
45  case BuiltinType::Id: \
46  return llvm::IntegerType::getInt64Ty(CGM.getLLVMContext());
47 #include "clang/Basic/OpenCLImageTypes.def"
48 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
49  case BuiltinType::Sampled##Id: \
50  return llvm::StructType::get( \
51  llvm::IntegerType::getInt64Ty(CGM.getLLVMContext()), \
52  llvm::IntegerType::getInt32Ty(CGM.getLLVMContext()));
53 #define IMAGE_WRITE_TYPE(Type, Id, Ext)
54 #define IMAGE_READ_WRITE_TYPE(Type, Id, Ext)
55 #include "clang/Basic/OpenCLImageTypes.def"
56  case BuiltinType::OCLSampler:
57  return llvm::IntegerType::getInt32Ty(CGM.getLLVMContext());
58  }
59  }
60 
61  if (T->isSamplerT())
62  return getSamplerType(T);
63 
64  return getPointerType(T);
65 }
66 
67 llvm::PointerType *CGOpenCLRuntime::getPointerType(const Type *T) {
70  return llvm::PointerType::get(CGM.getLLVMContext(), AddrSpc);
71 }
72 
74  if (llvm::Type *PipeTy = CGM.getTargetCodeGenInfo().getOpenCLType(CGM, T))
75  return PipeTy;
76 
77  if (T->isReadOnly())
78  return getPipeType(T, "opencl.pipe_ro_t", PipeROTy);
79  else
80  return getPipeType(T, "opencl.pipe_wo_t", PipeWOTy);
81 }
82 
83 llvm::Type *CGOpenCLRuntime::getPipeType(const PipeType *T, StringRef Name,
84  llvm::Type *&PipeTy) {
85  if (!PipeTy)
86  PipeTy = getPointerType(T);
87  return PipeTy;
88 }
89 
90 llvm::Type *CGOpenCLRuntime::getSamplerType(const Type *T) {
91  if (SamplerTy)
92  return SamplerTy;
93 
94  if (llvm::Type *TransTy = CGM.getTargetCodeGenInfo().getOpenCLType(
96  SamplerTy = TransTy;
97  else
99  return SamplerTy;
100 }
101 
102 llvm::Value *CGOpenCLRuntime::getPipeElemSize(const Expr *PipeArg) {
103  const PipeType *PipeTy = PipeArg->getType()->castAs<PipeType>();
104  // The type of the last (implicit) argument to be passed.
105  llvm::Type *Int32Ty = llvm::IntegerType::getInt32Ty(CGM.getLLVMContext());
106  unsigned TypeSize = CGM.getContext()
108  .getQuantity();
109  return llvm::ConstantInt::get(Int32Ty, TypeSize, false);
110 }
111 
112 llvm::Value *CGOpenCLRuntime::getPipeElemAlign(const Expr *PipeArg) {
113  const PipeType *PipeTy = PipeArg->getType()->castAs<PipeType>();
114  // The type of the last (implicit) argument to be passed.
115  llvm::Type *Int32Ty = llvm::IntegerType::getInt32Ty(CGM.getLLVMContext());
116  unsigned TypeSize = CGM.getContext()
118  .getQuantity();
119  return llvm::ConstantInt::get(Int32Ty, TypeSize, false);
120 }
121 
123  assert(CGM.getLangOpts().OpenCL);
124  return llvm::PointerType::get(
127 }
128 
129 // Get the block literal from an expression derived from the block expression.
130 // OpenCL v2.0 s6.12.5:
131 // Block variable declarations are implicitly qualified with const. Therefore
132 // all block variables must be initialized at declaration time and may not be
133 // reassigned.
134 static const BlockExpr *getBlockExpr(const Expr *E) {
135  const Expr *Prev = nullptr; // to make sure we do not stuck in infinite loop.
136  while(!isa<BlockExpr>(E) && E != Prev) {
137  Prev = E;
138  E = E->IgnoreCasts();
139  if (auto DR = dyn_cast<DeclRefExpr>(E)) {
140  E = cast<VarDecl>(DR->getDecl())->getInit();
141  }
142  }
143  return cast<BlockExpr>(E);
144 }
145 
146 /// Record emitted llvm invoke function and llvm block literal for the
147 /// corresponding block expression.
149  llvm::Function *InvokeF,
150  llvm::Value *Block, llvm::Type *BlockTy) {
151  assert(!EnqueuedBlockMap.contains(E) && "Block expression emitted twice");
152  assert(isa<llvm::Function>(InvokeF) && "Invalid invoke function");
153  assert(Block->getType()->isPointerTy() && "Invalid block literal type");
154  EnqueuedBlockMap[E].InvokeFunc = InvokeF;
155  EnqueuedBlockMap[E].BlockArg = Block;
156  EnqueuedBlockMap[E].BlockTy = BlockTy;
157  EnqueuedBlockMap[E].KernelHandle = nullptr;
158 }
159 
160 llvm::Function *CGOpenCLRuntime::getInvokeFunction(const Expr *E) {
161  return EnqueuedBlockMap[getBlockExpr(E)].InvokeFunc;
162 }
163 
166  CGF.EmitScalarExpr(E);
167 
168  // The block literal may be assigned to a const variable. Chasing down
169  // to get the block literal.
170  const BlockExpr *Block = getBlockExpr(E);
171 
172  assert(EnqueuedBlockMap.contains(Block) && "Block expression not emitted");
173 
174  // Do not emit the block wrapper again if it has been emitted.
175  if (EnqueuedBlockMap[Block].KernelHandle) {
176  return EnqueuedBlockMap[Block];
177  }
178 
180  CGF, EnqueuedBlockMap[Block].InvokeFunc, EnqueuedBlockMap[Block].BlockTy);
181 
182  // The common part of the post-processing of the kernel goes here.
183  EnqueuedBlockMap[Block].KernelHandle = F;
184  return EnqueuedBlockMap[Block];
185 }
static const BlockExpr * getBlockExpr(const Expr *E)
const Decl * D
Expr * E
static Decl::Kind getKind(const Decl *D)
Definition: DeclBase.cpp:1171
const CFGBlock * Block
Definition: HTMLLogger.cpp:153
LangAS getOpenCLTypeAddrSpace(const Type *T) const
Get address space for OpenCL type.
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
CharUnits getTypeSizeInChars(QualType T) const
Return the size of the specified (complete) type T, in characters.
CanQualType OCLSamplerTy
Definition: ASTContext.h:1161
unsigned getTargetAddressSpace(LangAS AS) const
BlockExpr - Adaptor class for mixing a BlockDecl with expressions.
Definition: Expr.h:6396
const T * getTypePtr() const
Retrieve the underlying type pointer, which refers to a canonical type.
Definition: CanonicalType.h:83
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Definition: CharUnits.h:185
virtual llvm::Type * getPipeType(const PipeType *T, StringRef Name, llvm::Type *&PipeTy)
EnqueuedBlockInfo emitOpenCLEnqueuedBlock(CodeGenFunction &CGF, const Expr *E)
llvm::PointerType * getPointerType(const Type *T)
virtual llvm::Value * getPipeElemAlign(const Expr *PipeArg)
llvm::Function * getInvokeFunction(const Expr *E)
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.
llvm::PointerType * getGenericVoidPointerType()
llvm::DenseMap< const Expr *, EnqueuedBlockInfo > EnqueuedBlockMap
Maps block expression to block information.
virtual llvm::Type * convertOpenCLSpecificType(const Type *T)
virtual llvm::Value * getPipeElemSize(const Expr *PipeArg)
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...
llvm::Type * getSamplerType(const Type *T)
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
void EmitStaticVarDecl(const VarDecl &D, llvm::GlobalValue::LinkageTypes Linkage)
Definition: CGDecl.cpp:420
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,...
const LangOptions & getLangOpts() const
const llvm::Triple & getTriple() const
llvm::LLVMContext & getLLVMContext()
const TargetCodeGenInfo & getTargetCodeGenInfo()
ASTContext & getContext() const
virtual llvm::Value * createEnqueuedBlockKernel(CodeGenFunction &CGF, llvm::Function *BlockInvokeFunc, llvm::Type *BlockTy) const
Create an OpenCL kernel for an enqueued block.
Definition: TargetInfo.cpp:178
virtual llvm::Type * getOpenCLType(CodeGenModule &CGM, const Type *T) const
Return an LLVM type that corresponds to an OpenCL type.
Definition: TargetInfo.h:417
This represents one expression.
Definition: Expr.h:110
Expr * IgnoreCasts() LLVM_READONLY
Skip past any casts which might surround this expression until reaching a fixed point.
Definition: Expr.cpp:3106
QualType getType() const
Definition: Expr.h:142
PipeType - OpenCL20.
Definition: Type.h:7609
QualType getElementType() const
Definition: Type.h:7620
The base class of the type hierarchy.
Definition: Type.h:1829
const T * castAs() const
Member-template castAs<specific type>.
Definition: Type.h:8635
bool isOpenCLSpecificType() const
Definition: Type.h:8294
bool isSamplerT() const
Definition: Type.h:8228
Represents a variable declaration or definition.
Definition: Decl.h:880
The JSON file list parser is used to communicate input to InstallAPI.
const FunctionProtoType * T
unsigned int uint32_t
Structure for enqueued block information.