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:
TCETargetCodeGenInfo(CodeGenTypes & CGT)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
setTargetAttributes(const Decl * D,llvm::GlobalValue * GV,CodeGen::CodeGenModule & M) const32 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<OpenCLKernelAttr>()) {
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 SmallVector<llvm::Metadata *, 5> Operands;
54 Operands.push_back(llvm::ConstantAsMetadata::get(F));
55
56 Operands.push_back(
57 llvm::ConstantAsMetadata::get(llvm::Constant::getIntegerValue(
58 M.Int32Ty, llvm::APInt(32, Attr->getXDim()))));
59 Operands.push_back(
60 llvm::ConstantAsMetadata::get(llvm::Constant::getIntegerValue(
61 M.Int32Ty, llvm::APInt(32, Attr->getYDim()))));
62 Operands.push_back(
63 llvm::ConstantAsMetadata::get(llvm::Constant::getIntegerValue(
64 M.Int32Ty, llvm::APInt(32, Attr->getZDim()))));
65
66 // Add a boolean constant operand for "required" (true) or "hint"
67 // (false) for implementing the work_group_size_hint attr later.
68 // Currently always true as the hint is not yet implemented.
69 Operands.push_back(
70 llvm::ConstantAsMetadata::get(llvm::ConstantInt::getTrue(Context)));
71 OpenCLMetadata->addOperand(llvm::MDNode::get(Context, Operands));
72 }
73 }
74 }
75 }
76
77 }
78
79 std::unique_ptr<TargetCodeGenInfo>
createTCETargetCodeGenInfo(CodeGenModule & CGM)80 CodeGen::createTCETargetCodeGenInfo(CodeGenModule &CGM) {
81 return std::make_unique<TCETargetCodeGenInfo>(CGM.getTypes());
82 }
83