1 //===- TCE.cpp ------------------------------------------------------------===// 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 #include "ABIInfoImpl.h" 10 #include "TargetInfo.h" 11 12 using namespace clang; 13 using namespace clang::CodeGen; 14 15 //===----------------------------------------------------------------------===// 16 // TCE ABI Implementation (see http://tce.cs.tut.fi). Uses mostly the defaults. 17 // Currently subclassed only to implement custom OpenCL C function attribute 18 // handling. 19 //===----------------------------------------------------------------------===// 20 21 namespace { 22 23 class TCETargetCodeGenInfo : public TargetCodeGenInfo { 24 public: 25 TCETargetCodeGenInfo(CodeGenTypes &CGT) 26 : TargetCodeGenInfo(std::make_unique<DefaultABIInfo>(CGT)) {} 27 28 void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV, 29 CodeGen::CodeGenModule &M) const override; 30 }; 31 32 void TCETargetCodeGenInfo::setTargetAttributes( 33 const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const { 34 if (GV->isDeclaration()) 35 return; 36 const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D); 37 if (!FD) return; 38 39 llvm::Function *F = cast<llvm::Function>(GV); 40 41 if (M.getLangOpts().OpenCL) { 42 if (FD->hasAttr<DeviceKernelAttr>()) { 43 // OpenCL C Kernel functions are not subject to inlining 44 F->addFnAttr(llvm::Attribute::NoInline); 45 const ReqdWorkGroupSizeAttr *Attr = FD->getAttr<ReqdWorkGroupSizeAttr>(); 46 if (Attr) { 47 // Convert the reqd_work_group_size() attributes to metadata. 48 llvm::LLVMContext &Context = F->getContext(); 49 llvm::NamedMDNode *OpenCLMetadata = 50 M.getModule().getOrInsertNamedMetadata( 51 "opencl.kernel_wg_size_info"); 52 53 auto Eval = [&](Expr *E) { 54 return E->EvaluateKnownConstInt(FD->getASTContext()); 55 }; 56 SmallVector<llvm::Metadata *, 5> Operands{ 57 llvm::ConstantAsMetadata::get(F), 58 llvm::ConstantAsMetadata::get(llvm::Constant::getIntegerValue( 59 M.Int32Ty, Eval(Attr->getXDim()))), 60 llvm::ConstantAsMetadata::get(llvm::Constant::getIntegerValue( 61 M.Int32Ty, Eval(Attr->getYDim()))), 62 llvm::ConstantAsMetadata::get(llvm::Constant::getIntegerValue( 63 M.Int32Ty, Eval(Attr->getZDim()))), 64 // Add a boolean constant operand for "required" (true) or "hint" 65 // (false) for implementing the work_group_size_hint attr later. 66 // Currently always true as the hint is not yet implemented. 67 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getTrue(Context))}; 68 OpenCLMetadata->addOperand(llvm::MDNode::get(Context, Operands)); 69 } 70 } 71 } 72 } 73 74 } 75 76 std::unique_ptr<TargetCodeGenInfo> 77 CodeGen::createTCETargetCodeGenInfo(CodeGenModule &CGM) { 78 return std::make_unique<TCETargetCodeGenInfo>(CGM.getTypes()); 79 } 80