1 //===---- TargetInfo.cpp - Encapsulate target details -----------*- C++ -*-===//
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 // These classes wrap the information about a call or function
10 // definition used to handle ABI compliancy.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "TargetInfo.h"
15 #include "ABIInfo.h"
16 #include "ABIInfoImpl.h"
17 #include "CodeGenFunction.h"
18 #include "clang/Basic/CodeGenOptions.h"
19 #include "clang/CodeGen/CGFunctionInfo.h"
20 #include "llvm/ADT/StringExtras.h"
21 #include "llvm/ADT/Twine.h"
22 #include "llvm/IR/Type.h"
23 #include "llvm/Support/raw_ostream.h"
24 
25 using namespace clang;
26 using namespace CodeGen;
27 
28 LLVM_DUMP_METHOD void ABIArgInfo::dump() const {
29   raw_ostream &OS = llvm::errs();
30   OS << "(ABIArgInfo Kind=";
31   switch (TheKind) {
32   case Direct:
33     OS << "Direct Type=";
34     if (llvm::Type *Ty = getCoerceToType())
35       Ty->print(OS);
36     else
37       OS << "null";
38     break;
39   case Extend:
40     OS << "Extend";
41     break;
42   case Ignore:
43     OS << "Ignore";
44     break;
45   case InAlloca:
46     OS << "InAlloca Offset=" << getInAllocaFieldIndex();
47     break;
48   case Indirect:
49     OS << "Indirect Align=" << getIndirectAlign().getQuantity()
50        << " ByVal=" << getIndirectByVal()
51        << " Realign=" << getIndirectRealign();
52     break;
53   case IndirectAliased:
54     OS << "Indirect Align=" << getIndirectAlign().getQuantity()
55        << " AadrSpace=" << getIndirectAddrSpace()
56        << " Realign=" << getIndirectRealign();
57     break;
58   case Expand:
59     OS << "Expand";
60     break;
61   case CoerceAndExpand:
62     OS << "CoerceAndExpand Type=";
63     getCoerceAndExpandType()->print(OS);
64     break;
65   }
66   OS << ")\n";
67 }
68 
69 TargetCodeGenInfo::TargetCodeGenInfo(std::unique_ptr<ABIInfo> Info)
70     : Info(std::move(Info)) {}
71 
72 TargetCodeGenInfo::~TargetCodeGenInfo() = default;
73 
74 // If someone can figure out a general rule for this, that would be great.
75 // It's probably just doomed to be platform-dependent, though.
76 unsigned TargetCodeGenInfo::getSizeOfUnwindException() const {
77   // Verified for:
78   //   x86-64     FreeBSD, Linux, Darwin
79   //   x86-32     FreeBSD, Linux, Darwin
80   //   PowerPC    Linux
81   //   ARM        Darwin (*not* EABI)
82   //   AArch64    Linux
83   return 32;
84 }
85 
86 bool TargetCodeGenInfo::isNoProtoCallVariadic(const CallArgList &args,
87                                      const FunctionNoProtoType *fnType) const {
88   // The following conventions are known to require this to be false:
89   //   x86_stdcall
90   //   MIPS
91   // For everything else, we just prefer false unless we opt out.
92   return false;
93 }
94 
95 void
96 TargetCodeGenInfo::getDependentLibraryOption(llvm::StringRef Lib,
97                                              llvm::SmallString<24> &Opt) const {
98   // This assumes the user is passing a library name like "rt" instead of a
99   // filename like "librt.a/so", and that they don't care whether it's static or
100   // dynamic.
101   Opt = "-l";
102   Opt += Lib;
103 }
104 
105 unsigned TargetCodeGenInfo::getOpenCLKernelCallingConv() const {
106   // OpenCL kernels are called via an explicit runtime API with arguments
107   // set with clSetKernelArg(), not as normal sub-functions.
108   // Return SPIR_KERNEL by default as the kernel calling convention to
109   // ensure the fingerprint is fixed such way that each OpenCL argument
110   // gets one matching argument in the produced kernel function argument
111   // list to enable feasible implementation of clSetKernelArg() with
112   // aggregates etc. In case we would use the default C calling conv here,
113   // clSetKernelArg() might break depending on the target-specific
114   // conventions; different targets might split structs passed as values
115   // to multiple function arguments etc.
116   return llvm::CallingConv::SPIR_KERNEL;
117 }
118 
119 llvm::Constant *TargetCodeGenInfo::getNullPointer(const CodeGen::CodeGenModule &CGM,
120     llvm::PointerType *T, QualType QT) const {
121   return llvm::ConstantPointerNull::get(T);
122 }
123 
124 LangAS TargetCodeGenInfo::getGlobalVarAddressSpace(CodeGenModule &CGM,
125                                                    const VarDecl *D) const {
126   assert(!CGM.getLangOpts().OpenCL &&
127          !(CGM.getLangOpts().CUDA && CGM.getLangOpts().CUDAIsDevice) &&
128          "Address space agnostic languages only");
129   return D ? D->getType().getAddressSpace() : LangAS::Default;
130 }
131 
132 llvm::Value *TargetCodeGenInfo::performAddrSpaceCast(
133     CodeGen::CodeGenFunction &CGF, llvm::Value *Src, LangAS SrcAddr,
134     LangAS DestAddr, llvm::Type *DestTy, bool isNonNull) const {
135   // Since target may map different address spaces in AST to the same address
136   // space, an address space conversion may end up as a bitcast.
137   if (auto *C = dyn_cast<llvm::Constant>(Src))
138     return performAddrSpaceCast(CGF.CGM, C, SrcAddr, DestAddr, DestTy);
139   // Try to preserve the source's name to make IR more readable.
140   return CGF.Builder.CreateAddrSpaceCast(
141       Src, DestTy, Src->hasName() ? Src->getName() + ".ascast" : "");
142 }
143 
144 llvm::Constant *
145 TargetCodeGenInfo::performAddrSpaceCast(CodeGenModule &CGM, llvm::Constant *Src,
146                                         LangAS SrcAddr, LangAS DestAddr,
147                                         llvm::Type *DestTy) const {
148   // Since target may map different address spaces in AST to the same address
149   // space, an address space conversion may end up as a bitcast.
150   return llvm::ConstantExpr::getPointerCast(Src, DestTy);
151 }
152 
153 llvm::SyncScope::ID
154 TargetCodeGenInfo::getLLVMSyncScopeID(const LangOptions &LangOpts,
155                                       SyncScope Scope,
156                                       llvm::AtomicOrdering Ordering,
157                                       llvm::LLVMContext &Ctx) const {
158   return Ctx.getOrInsertSyncScopeID(""); /* default sync scope */
159 }
160 
161 void TargetCodeGenInfo::addStackProbeTargetAttributes(
162     const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &CGM) const {
163   if (llvm::Function *Fn = dyn_cast_or_null<llvm::Function>(GV)) {
164     if (CGM.getCodeGenOpts().StackProbeSize != 4096)
165       Fn->addFnAttr("stack-probe-size",
166                     llvm::utostr(CGM.getCodeGenOpts().StackProbeSize));
167     if (CGM.getCodeGenOpts().NoStackArgProbe)
168       Fn->addFnAttr("no-stack-arg-probe");
169   }
170 }
171 
172 /// Create an OpenCL kernel for an enqueued block.
173 ///
174 /// The kernel has the same function type as the block invoke function. Its
175 /// name is the name of the block invoke function postfixed with "_kernel".
176 /// It simply calls the block invoke function then returns.
177 llvm::Value *TargetCodeGenInfo::createEnqueuedBlockKernel(
178     CodeGenFunction &CGF, llvm::Function *Invoke, llvm::Type *BlockTy) const {
179   auto *InvokeFT = Invoke->getFunctionType();
180   auto &C = CGF.getLLVMContext();
181   std::string Name = Invoke->getName().str() + "_kernel";
182   auto *FT = llvm::FunctionType::get(llvm::Type::getVoidTy(C),
183                                      InvokeFT->params(), false);
184   auto *F = llvm::Function::Create(FT, llvm::GlobalValue::ExternalLinkage, Name,
185                                    &CGF.CGM.getModule());
186   llvm::CallingConv::ID KernelCC =
187       CGF.getTypes().ClangCallConvToLLVMCallConv(CallingConv::CC_OpenCLKernel);
188   F->setCallingConv(KernelCC);
189 
190   llvm::AttrBuilder KernelAttrs(C);
191 
192   // FIXME: This is missing setTargetAttributes
193   CGF.CGM.addDefaultFunctionDefinitionAttributes(KernelAttrs);
194   F->addFnAttrs(KernelAttrs);
195 
196   auto IP = CGF.Builder.saveIP();
197   auto *BB = llvm::BasicBlock::Create(C, "entry", F);
198   auto &Builder = CGF.Builder;
199   Builder.SetInsertPoint(BB);
200   llvm::SmallVector<llvm::Value *, 2> Args(llvm::make_pointer_range(F->args()));
201   llvm::CallInst *Call = Builder.CreateCall(Invoke, Args);
202   Call->setCallingConv(Invoke->getCallingConv());
203 
204   Builder.CreateRetVoid();
205   Builder.restoreIP(IP);
206   return F;
207 }
208 
209 namespace {
210 class DefaultTargetCodeGenInfo : public TargetCodeGenInfo {
211 public:
212   DefaultTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT)
213       : TargetCodeGenInfo(std::make_unique<DefaultABIInfo>(CGT)) {}
214 };
215 } // namespace
216 
217 std::unique_ptr<TargetCodeGenInfo>
218 CodeGen::createDefaultTargetCodeGenInfo(CodeGenModule &CGM) {
219   return std::make_unique<DefaultTargetCodeGenInfo>(CGM.getTypes());
220 }
221