xref: /freebsd/contrib/llvm-project/clang/lib/CodeGen/Targets/TCE.cpp (revision e64bea71c21eb42e97aa615188ba91f6cce0d36d)
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