diff options
author | Anastasia Stulova <anastasia.stulova@arm.com> | 2019-05-09 13:55:44 +0000 |
---|---|---|
committer | Anastasia Stulova <anastasia.stulova@arm.com> | 2019-05-09 13:55:44 +0000 |
commit | e6cf6c78f88ffb7eed69b0eaa60785eab9df2b88 (patch) | |
tree | bfe60eb40c0baae3646a31c2524fbe8bc1b27e9a /clang/lib/CodeGen/CodeGenFunction.cpp | |
parent | 9db0e72570f73e4e8aaf870201f2c1bc738baee3 (diff) | |
download | bcm5719-llvm-e6cf6c78f88ffb7eed69b0eaa60785eab9df2b88.tar.gz bcm5719-llvm-e6cf6c78f88ffb7eed69b0eaa60785eab9df2b88.zip |
[OpenCL] Make global ctor init function a kernel
We need to be able to enqueue internal function that initializes
global constructors on the host side. Therefore it has to be
converted to a kernel.
This change factors out common logic for adding kernel metadata
and moves it from CodeGenFunction to CodeGenModule in order to
make it accessible for the extra use case.
Differential revision: https://reviews.llvm.org/D61488
llvm-svn: 360342
Diffstat (limited to 'clang/lib/CodeGen/CodeGenFunction.cpp')
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.cpp | 201 |
1 files changed, 1 insertions, 200 deletions
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index d7bb4a54c1b..a2d6d59800c 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -536,205 +536,6 @@ CodeGenFunction::DecodeAddrUsedInPrologue(llvm::Value *F, "decoded_addr"); } -static void removeImageAccessQualifier(std::string& TyName) { - std::string ReadOnlyQual("__read_only"); - std::string::size_type ReadOnlyPos = TyName.find(ReadOnlyQual); - if (ReadOnlyPos != std::string::npos) - // "+ 1" for the space after access qualifier. - TyName.erase(ReadOnlyPos, ReadOnlyQual.size() + 1); - else { - std::string WriteOnlyQual("__write_only"); - std::string::size_type WriteOnlyPos = TyName.find(WriteOnlyQual); - if (WriteOnlyPos != std::string::npos) - TyName.erase(WriteOnlyPos, WriteOnlyQual.size() + 1); - else { - std::string ReadWriteQual("__read_write"); - std::string::size_type ReadWritePos = TyName.find(ReadWriteQual); - if (ReadWritePos != std::string::npos) - TyName.erase(ReadWritePos, ReadWriteQual.size() + 1); - } - } -} - -// Returns the address space id that should be produced to the -// kernel_arg_addr_space metadata. This is always fixed to the ids -// as specified in the SPIR 2.0 specification in order to differentiate -// for example in clGetKernelArgInfo() implementation between the address -// spaces with targets without unique mapping to the OpenCL address spaces -// (basically all single AS CPUs). -static unsigned ArgInfoAddressSpace(LangAS AS) { - switch (AS) { - case LangAS::opencl_global: return 1; - case LangAS::opencl_constant: return 2; - case LangAS::opencl_local: return 3; - case LangAS::opencl_generic: return 4; // Not in SPIR 2.0 specs. - default: - return 0; // Assume private. - } -} - -// OpenCL v1.2 s5.6.4.6 allows the compiler to store kernel argument -// information in the program executable. The argument information stored -// includes the argument name, its type, the address and access qualifiers used. -static void GenOpenCLArgMetadata(const FunctionDecl *FD, llvm::Function *Fn, - CodeGenModule &CGM, llvm::LLVMContext &Context, - CGBuilderTy &Builder, ASTContext &ASTCtx) { - // Create MDNodes that represent the kernel arg metadata. - // Each MDNode is a list in the form of "key", N number of values which is - // the same number of values as their are kernel arguments. - - const PrintingPolicy &Policy = ASTCtx.getPrintingPolicy(); - - // MDNode for the kernel argument address space qualifiers. - SmallVector<llvm::Metadata *, 8> addressQuals; - - // MDNode for the kernel argument access qualifiers (images only). - SmallVector<llvm::Metadata *, 8> accessQuals; - - // MDNode for the kernel argument type names. - SmallVector<llvm::Metadata *, 8> argTypeNames; - - // MDNode for the kernel argument base type names. - SmallVector<llvm::Metadata *, 8> argBaseTypeNames; - - // MDNode for the kernel argument type qualifiers. - SmallVector<llvm::Metadata *, 8> argTypeQuals; - - // MDNode for the kernel argument names. - SmallVector<llvm::Metadata *, 8> argNames; - - for (unsigned i = 0, e = FD->getNumParams(); i != e; ++i) { - const ParmVarDecl *parm = FD->getParamDecl(i); - QualType ty = parm->getType(); - std::string typeQuals; - - if (ty->isPointerType()) { - QualType pointeeTy = ty->getPointeeType(); - - // Get address qualifier. - addressQuals.push_back(llvm::ConstantAsMetadata::get(Builder.getInt32( - ArgInfoAddressSpace(pointeeTy.getAddressSpace())))); - - // Get argument type name. - std::string typeName = - pointeeTy.getUnqualifiedType().getAsString(Policy) + "*"; - - // Turn "unsigned type" to "utype" - std::string::size_type pos = typeName.find("unsigned"); - if (pointeeTy.isCanonical() && pos != std::string::npos) - typeName.erase(pos+1, 8); - - argTypeNames.push_back(llvm::MDString::get(Context, typeName)); - - std::string baseTypeName = - pointeeTy.getUnqualifiedType().getCanonicalType().getAsString( - Policy) + - "*"; - - // Turn "unsigned type" to "utype" - pos = baseTypeName.find("unsigned"); - if (pos != std::string::npos) - baseTypeName.erase(pos+1, 8); - - argBaseTypeNames.push_back(llvm::MDString::get(Context, baseTypeName)); - - // Get argument type qualifiers: - if (ty.isRestrictQualified()) - typeQuals = "restrict"; - if (pointeeTy.isConstQualified() || - (pointeeTy.getAddressSpace() == LangAS::opencl_constant)) - typeQuals += typeQuals.empty() ? "const" : " const"; - if (pointeeTy.isVolatileQualified()) - typeQuals += typeQuals.empty() ? "volatile" : " volatile"; - } else { - uint32_t AddrSpc = 0; - bool isPipe = ty->isPipeType(); - if (ty->isImageType() || isPipe) - AddrSpc = ArgInfoAddressSpace(LangAS::opencl_global); - - addressQuals.push_back( - llvm::ConstantAsMetadata::get(Builder.getInt32(AddrSpc))); - - // Get argument type name. - std::string typeName; - if (isPipe) - typeName = ty.getCanonicalType()->getAs<PipeType>()->getElementType() - .getAsString(Policy); - else - typeName = ty.getUnqualifiedType().getAsString(Policy); - - // Turn "unsigned type" to "utype" - std::string::size_type pos = typeName.find("unsigned"); - if (ty.isCanonical() && pos != std::string::npos) - typeName.erase(pos+1, 8); - - std::string baseTypeName; - if (isPipe) - baseTypeName = ty.getCanonicalType()->getAs<PipeType>() - ->getElementType().getCanonicalType() - .getAsString(Policy); - else - baseTypeName = - ty.getUnqualifiedType().getCanonicalType().getAsString(Policy); - - // Remove access qualifiers on images - // (as they are inseparable from type in clang implementation, - // but OpenCL spec provides a special query to get access qualifier - // via clGetKernelArgInfo with CL_KERNEL_ARG_ACCESS_QUALIFIER): - if (ty->isImageType()) { - removeImageAccessQualifier(typeName); - removeImageAccessQualifier(baseTypeName); - } - - argTypeNames.push_back(llvm::MDString::get(Context, typeName)); - - // Turn "unsigned type" to "utype" - pos = baseTypeName.find("unsigned"); - if (pos != std::string::npos) - baseTypeName.erase(pos+1, 8); - - argBaseTypeNames.push_back(llvm::MDString::get(Context, baseTypeName)); - - if (isPipe) - typeQuals = "pipe"; - } - - argTypeQuals.push_back(llvm::MDString::get(Context, typeQuals)); - - // Get image and pipe access qualifier: - if (ty->isImageType()|| ty->isPipeType()) { - const Decl *PDecl = parm; - if (auto *TD = dyn_cast<TypedefType>(ty)) - PDecl = TD->getDecl(); - const OpenCLAccessAttr *A = PDecl->getAttr<OpenCLAccessAttr>(); - if (A && A->isWriteOnly()) - accessQuals.push_back(llvm::MDString::get(Context, "write_only")); - else if (A && A->isReadWrite()) - accessQuals.push_back(llvm::MDString::get(Context, "read_write")); - else - accessQuals.push_back(llvm::MDString::get(Context, "read_only")); - } else - accessQuals.push_back(llvm::MDString::get(Context, "none")); - - // Get argument name. - argNames.push_back(llvm::MDString::get(Context, parm->getName())); - } - - Fn->setMetadata("kernel_arg_addr_space", - llvm::MDNode::get(Context, addressQuals)); - Fn->setMetadata("kernel_arg_access_qual", - llvm::MDNode::get(Context, accessQuals)); - Fn->setMetadata("kernel_arg_type", - llvm::MDNode::get(Context, argTypeNames)); - Fn->setMetadata("kernel_arg_base_type", - llvm::MDNode::get(Context, argBaseTypeNames)); - Fn->setMetadata("kernel_arg_type_qual", - llvm::MDNode::get(Context, argTypeQuals)); - if (CGM.getCodeGenOpts().EmitOpenCLArgMetadata) - Fn->setMetadata("kernel_arg_name", - llvm::MDNode::get(Context, argNames)); -} - void CodeGenFunction::EmitOpenCLKernelMetadata(const FunctionDecl *FD, llvm::Function *Fn) { @@ -743,7 +544,7 @@ void CodeGenFunction::EmitOpenCLKernelMetadata(const FunctionDecl *FD, llvm::LLVMContext &Context = getLLVMContext(); - GenOpenCLArgMetadata(FD, Fn, CGM, Context, Builder, getContext()); + CGM.GenOpenCLArgMetadata(Fn, FD, this); if (const VecTypeHintAttr *A = FD->getAttr<VecTypeHintAttr>()) { QualType HintQTy = A->getTypeHint(); |