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 "llvm/IR/DerivedTypes.h" 20 #include "llvm/IR/GlobalValue.h" 21 #include <assert.h> 22 23 using namespace clang; 24 using namespace CodeGen; 25 26 CGOpenCLRuntime::~CGOpenCLRuntime() {} 27 28 void CGOpenCLRuntime::EmitWorkGroupLocalVarDecl(CodeGenFunction &CGF, 29 const VarDecl &D) { 30 return CGF.EmitStaticVarDecl(D, llvm::GlobalValue::InternalLinkage); 31 } 32 33 llvm::Type *CGOpenCLRuntime::convertOpenCLSpecificType(const Type *T) { 34 assert(T->isOpenCLSpecificType() && 35 "Not an OpenCL specific type!"); 36 37 llvm::LLVMContext& Ctx = CGM.getLLVMContext(); 38 uint32_t ImgAddrSpc = CGM.getContext().getTargetAddressSpace( 39 CGM.getTarget().getOpenCLImageAddrSpace()); 40 switch (cast<BuiltinType>(T)->getKind()) { 41 default: 42 llvm_unreachable("Unexpected opencl builtin type!"); 43 return nullptr; 44 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ 45 case BuiltinType::Id: \ 46 return llvm::PointerType::get( \ 47 llvm::StructType::create(Ctx, "opencl." #ImgType "_" #Suffix "_t"), \ 48 ImgAddrSpc); 49 #include "clang/Basic/OpenCLImageTypes.def" 50 case BuiltinType::OCLSampler: 51 return getSamplerType(); 52 case BuiltinType::OCLEvent: 53 return llvm::PointerType::get(llvm::StructType::create( 54 Ctx, "opencl.event_t"), 0); 55 case BuiltinType::OCLClkEvent: 56 return llvm::PointerType::get( 57 llvm::StructType::create(Ctx, "opencl.clk_event_t"), 0); 58 case BuiltinType::OCLQueue: 59 return llvm::PointerType::get( 60 llvm::StructType::create(Ctx, "opencl.queue_t"), 0); 61 case BuiltinType::OCLNDRange: 62 return llvm::PointerType::get( 63 llvm::StructType::create(Ctx, "opencl.ndrange_t"), 0); 64 case BuiltinType::OCLReserveID: 65 return llvm::PointerType::get( 66 llvm::StructType::create(Ctx, "opencl.reserve_id_t"), 0); 67 } 68 } 69 70 llvm::Type *CGOpenCLRuntime::getPipeType() { 71 if (!PipeTy){ 72 uint32_t PipeAddrSpc = 73 CGM.getContext().getTargetAddressSpace(LangAS::opencl_global); 74 PipeTy = llvm::PointerType::get(llvm::StructType::create( 75 CGM.getLLVMContext(), "opencl.pipe_t"), PipeAddrSpc); 76 } 77 78 return PipeTy; 79 } 80 81 llvm::PointerType *CGOpenCLRuntime::getSamplerType() { 82 if (!SamplerTy) 83 SamplerTy = llvm::PointerType::get(llvm::StructType::create( 84 CGM.getLLVMContext(), "opencl.sampler_t"), 85 CGM.getContext().getTargetAddressSpace( 86 LangAS::opencl_constant)); 87 return SamplerTy; 88 } 89 90 llvm::Value *CGOpenCLRuntime::getPipeElemSize(const Expr *PipeArg) { 91 const PipeType *PipeTy = PipeArg->getType()->getAs<PipeType>(); 92 // The type of the last (implicit) argument to be passed. 93 llvm::Type *Int32Ty = llvm::IntegerType::getInt32Ty(CGM.getLLVMContext()); 94 unsigned TypeSize = CGM.getContext() 95 .getTypeSizeInChars(PipeTy->getElementType()) 96 .getQuantity(); 97 return llvm::ConstantInt::get(Int32Ty, TypeSize, false); 98 } 99 100 llvm::Value *CGOpenCLRuntime::getPipeElemAlign(const Expr *PipeArg) { 101 const PipeType *PipeTy = PipeArg->getType()->getAs<PipeType>(); 102 // The type of the last (implicit) argument to be passed. 103 llvm::Type *Int32Ty = llvm::IntegerType::getInt32Ty(CGM.getLLVMContext()); 104 unsigned TypeSize = CGM.getContext() 105 .getTypeAlignInChars(PipeTy->getElementType()) 106 .getQuantity(); 107 return llvm::ConstantInt::get(Int32Ty, TypeSize, false); 108 } 109