80 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8 9#include "ABIInfoImpl.h"10#include "TargetInfo.h"11 12using namespace clang;13using 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 attribute18// handling.19//===----------------------------------------------------------------------===//20 21namespace {22 23class TCETargetCodeGenInfo : public TargetCodeGenInfo {24public: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 32void 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 inlining44 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 76std::unique_ptr<TargetCodeGenInfo>77CodeGen::createTCETargetCodeGenInfo(CodeGenModule &CGM) {78 return std::make_unique<TCETargetCodeGenInfo>(CGM.getTypes());79}80