xref: /llvm-project/clang/lib/CodeGen/Targets/TCE.cpp (revision 992cb98462abb7630e87003516b75b241628f64c)
1*992cb984SSergei Barannikov //===- TCE.cpp ------------------------------------------------------------===//
2*992cb984SSergei Barannikov //
3*992cb984SSergei Barannikov // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*992cb984SSergei Barannikov // See https://llvm.org/LICENSE.txt for license information.
5*992cb984SSergei Barannikov // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*992cb984SSergei Barannikov //
7*992cb984SSergei Barannikov //===----------------------------------------------------------------------===//
8*992cb984SSergei Barannikov 
9*992cb984SSergei Barannikov #include "ABIInfoImpl.h"
10*992cb984SSergei Barannikov #include "TargetInfo.h"
11*992cb984SSergei Barannikov 
12*992cb984SSergei Barannikov using namespace clang;
13*992cb984SSergei Barannikov using namespace clang::CodeGen;
14*992cb984SSergei Barannikov 
15*992cb984SSergei Barannikov //===----------------------------------------------------------------------===//
16*992cb984SSergei Barannikov // TCE ABI Implementation (see http://tce.cs.tut.fi). Uses mostly the defaults.
17*992cb984SSergei Barannikov // Currently subclassed only to implement custom OpenCL C function attribute
18*992cb984SSergei Barannikov // handling.
19*992cb984SSergei Barannikov //===----------------------------------------------------------------------===//
20*992cb984SSergei Barannikov 
21*992cb984SSergei Barannikov namespace {
22*992cb984SSergei Barannikov 
23*992cb984SSergei Barannikov class TCETargetCodeGenInfo : public TargetCodeGenInfo {
24*992cb984SSergei Barannikov public:
TCETargetCodeGenInfo(CodeGenTypes & CGT)25*992cb984SSergei Barannikov   TCETargetCodeGenInfo(CodeGenTypes &CGT)
26*992cb984SSergei Barannikov       : TargetCodeGenInfo(std::make_unique<DefaultABIInfo>(CGT)) {}
27*992cb984SSergei Barannikov 
28*992cb984SSergei Barannikov   void setTargetAttributes(const Decl *D, llvm::GlobalValue *GV,
29*992cb984SSergei Barannikov                            CodeGen::CodeGenModule &M) const override;
30*992cb984SSergei Barannikov };
31*992cb984SSergei Barannikov 
setTargetAttributes(const Decl * D,llvm::GlobalValue * GV,CodeGen::CodeGenModule & M) const32*992cb984SSergei Barannikov void TCETargetCodeGenInfo::setTargetAttributes(
33*992cb984SSergei Barannikov     const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &M) const {
34*992cb984SSergei Barannikov   if (GV->isDeclaration())
35*992cb984SSergei Barannikov     return;
36*992cb984SSergei Barannikov   const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D);
37*992cb984SSergei Barannikov   if (!FD) return;
38*992cb984SSergei Barannikov 
39*992cb984SSergei Barannikov   llvm::Function *F = cast<llvm::Function>(GV);
40*992cb984SSergei Barannikov 
41*992cb984SSergei Barannikov   if (M.getLangOpts().OpenCL) {
42*992cb984SSergei Barannikov     if (FD->hasAttr<OpenCLKernelAttr>()) {
43*992cb984SSergei Barannikov       // OpenCL C Kernel functions are not subject to inlining
44*992cb984SSergei Barannikov       F->addFnAttr(llvm::Attribute::NoInline);
45*992cb984SSergei Barannikov       const ReqdWorkGroupSizeAttr *Attr = FD->getAttr<ReqdWorkGroupSizeAttr>();
46*992cb984SSergei Barannikov       if (Attr) {
47*992cb984SSergei Barannikov         // Convert the reqd_work_group_size() attributes to metadata.
48*992cb984SSergei Barannikov         llvm::LLVMContext &Context = F->getContext();
49*992cb984SSergei Barannikov         llvm::NamedMDNode *OpenCLMetadata =
50*992cb984SSergei Barannikov             M.getModule().getOrInsertNamedMetadata(
51*992cb984SSergei Barannikov                 "opencl.kernel_wg_size_info");
52*992cb984SSergei Barannikov 
53*992cb984SSergei Barannikov         SmallVector<llvm::Metadata *, 5> Operands;
54*992cb984SSergei Barannikov         Operands.push_back(llvm::ConstantAsMetadata::get(F));
55*992cb984SSergei Barannikov 
56*992cb984SSergei Barannikov         Operands.push_back(
57*992cb984SSergei Barannikov             llvm::ConstantAsMetadata::get(llvm::Constant::getIntegerValue(
58*992cb984SSergei Barannikov                 M.Int32Ty, llvm::APInt(32, Attr->getXDim()))));
59*992cb984SSergei Barannikov         Operands.push_back(
60*992cb984SSergei Barannikov             llvm::ConstantAsMetadata::get(llvm::Constant::getIntegerValue(
61*992cb984SSergei Barannikov                 M.Int32Ty, llvm::APInt(32, Attr->getYDim()))));
62*992cb984SSergei Barannikov         Operands.push_back(
63*992cb984SSergei Barannikov             llvm::ConstantAsMetadata::get(llvm::Constant::getIntegerValue(
64*992cb984SSergei Barannikov                 M.Int32Ty, llvm::APInt(32, Attr->getZDim()))));
65*992cb984SSergei Barannikov 
66*992cb984SSergei Barannikov         // Add a boolean constant operand for "required" (true) or "hint"
67*992cb984SSergei Barannikov         // (false) for implementing the work_group_size_hint attr later.
68*992cb984SSergei Barannikov         // Currently always true as the hint is not yet implemented.
69*992cb984SSergei Barannikov         Operands.push_back(
70*992cb984SSergei Barannikov             llvm::ConstantAsMetadata::get(llvm::ConstantInt::getTrue(Context)));
71*992cb984SSergei Barannikov         OpenCLMetadata->addOperand(llvm::MDNode::get(Context, Operands));
72*992cb984SSergei Barannikov       }
73*992cb984SSergei Barannikov     }
74*992cb984SSergei Barannikov   }
75*992cb984SSergei Barannikov }
76*992cb984SSergei Barannikov 
77*992cb984SSergei Barannikov }
78*992cb984SSergei Barannikov 
79*992cb984SSergei Barannikov std::unique_ptr<TargetCodeGenInfo>
createTCETargetCodeGenInfo(CodeGenModule & CGM)80*992cb984SSergei Barannikov CodeGen::createTCETargetCodeGenInfo(CodeGenModule &CGM) {
81*992cb984SSergei Barannikov   return std::make_unique<TCETargetCodeGenInfo>(CGM.getTypes());
82*992cb984SSergei Barannikov }
83