clang 22.0.0git
TargetInfo.cpp
Go to the documentation of this file.
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"
20#include "llvm/ADT/StringExtras.h"
21#include "llvm/ADT/Twine.h"
22#include "llvm/IR/Function.h"
23#include "llvm/IR/Type.h"
24#include "llvm/Support/raw_ostream.h"
25
26using namespace clang;
27using namespace CodeGen;
28
29LLVM_DUMP_METHOD void ABIArgInfo::dump() const {
30 raw_ostream &OS = llvm::errs();
31 OS << "(ABIArgInfo Kind=";
32 switch (TheKind) {
33 case Direct:
34 OS << "Direct Type=";
35 if (llvm::Type *Ty = getCoerceToType())
36 Ty->print(OS);
37 else
38 OS << "null";
39 break;
40 case Extend:
41 OS << "Extend";
42 break;
43 case Ignore:
44 OS << "Ignore";
45 break;
46 case InAlloca:
47 OS << "InAlloca Offset=" << getInAllocaFieldIndex();
48 break;
49 case Indirect:
50 OS << "Indirect Align=" << getIndirectAlign().getQuantity()
51 << " ByVal=" << getIndirectByVal()
52 << " Realign=" << getIndirectRealign();
53 break;
54 case IndirectAliased:
55 OS << "Indirect Align=" << getIndirectAlign().getQuantity()
56 << " AadrSpace=" << getIndirectAddrSpace()
57 << " Realign=" << getIndirectRealign();
58 break;
59 case Expand:
60 OS << "Expand";
61 break;
62 case CoerceAndExpand:
63 OS << "CoerceAndExpand Type=";
64 getCoerceAndExpandType()->print(OS);
65 break;
66 case TargetSpecific:
67 OS << "TargetSpecific Type=";
68 if (llvm::Type *Ty = getCoerceToType())
69 Ty->print(OS);
70 else
71 OS << "null";
72 break;
73 }
74 OS << ")\n";
75}
76
77TargetCodeGenInfo::TargetCodeGenInfo(std::unique_ptr<ABIInfo> Info)
78 : Info(std::move(Info)) {}
79
81
82// If someone can figure out a general rule for this, that would be great.
83// It's probably just doomed to be platform-dependent, though.
85 // Verified for:
86 // x86-64 FreeBSD, Linux, Darwin
87 // x86-32 FreeBSD, Linux, Darwin
88 // PowerPC Linux
89 // ARM Darwin (*not* EABI)
90 // AArch64 Linux
91 return 32;
92}
93
95 const FunctionNoProtoType *fnType) const {
96 // The following conventions are known to require this to be false:
97 // x86_stdcall
98 // MIPS
99 // For everything else, we just prefer false unless we opt out.
100 return false;
101}
102
103void
105 llvm::SmallString<24> &Opt) const {
106 // This assumes the user is passing a library name like "rt" instead of a
107 // filename like "librt.a/so", and that they don't care whether it's static or
108 // dynamic.
109 Opt = "-l";
110 Opt += Lib;
111}
112
114 if (getABIInfo().getContext().getLangOpts().OpenCL) {
115 // Device kernels are called via an explicit runtime API with arguments,
116 // such as set with clSetKernelArg() for OpenCL, not as normal
117 // sub-functions. Return SPIR_KERNEL by default as the kernel calling
118 // convention to ensure the fingerprint is fixed such way that each kernel
119 // argument gets one matching argument in the produced kernel function
120 // argument list to enable feasible implementation of clSetKernelArg() with
121 // aggregates etc. In case we would use the default C calling conv here,
122 // clSetKernelArg() might break depending on the target-specific
123 // conventions; different targets might split structs passed as values
124 // to multiple function arguments etc.
125 return llvm::CallingConv::SPIR_KERNEL;
126 }
127 llvm_unreachable("Unknown kernel calling convention");
128}
129
131 const FunctionType *&FT) const {
132 FT = getABIInfo().getContext().adjustFunctionType(
133 FT, FT->getExtInfo().withCallingConv(CC_C));
134}
135
137 llvm::PointerType *T, QualType QT) const {
138 return llvm::ConstantPointerNull::get(T);
139}
140
142 const VarDecl *D) const {
143 assert(!CGM.getLangOpts().OpenCL &&
144 !(CGM.getLangOpts().CUDA && CGM.getLangOpts().CUDAIsDevice) &&
145 "Address space agnostic languages only");
146 return D ? D->getType().getAddressSpace() : LangAS::Default;
147}
148
150 CodeGen::CodeGenFunction &CGF, llvm::Value *Src, LangAS SrcAddr,
151 llvm::Type *DestTy, bool isNonNull) const {
152 // Since target may map different address spaces in AST to the same address
153 // space, an address space conversion may end up as a bitcast.
154 if (auto *C = dyn_cast<llvm::Constant>(Src))
155 return performAddrSpaceCast(CGF.CGM, C, SrcAddr, DestTy);
156 // Try to preserve the source's name to make IR more readable.
157 return CGF.Builder.CreateAddrSpaceCast(
158 Src, DestTy, Src->hasName() ? Src->getName() + ".ascast" : "");
159}
160
161llvm::Constant *
163 LangAS SrcAddr,
164 llvm::Type *DestTy) const {
165 // Since target may map different address spaces in AST to the same address
166 // space, an address space conversion may end up as a bitcast.
167 return llvm::ConstantExpr::getPointerCast(Src, DestTy);
168}
169
170llvm::SyncScope::ID
173 llvm::AtomicOrdering Ordering,
174 llvm::LLVMContext &Ctx) const {
175 return Ctx.getOrInsertSyncScopeID(""); /* default sync scope */
176}
177
179 const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &CGM) const {
180 if (llvm::Function *Fn = dyn_cast_or_null<llvm::Function>(GV)) {
181 if (CGM.getCodeGenOpts().StackProbeSize != 4096)
182 Fn->addFnAttr("stack-probe-size",
183 llvm::utostr(CGM.getCodeGenOpts().StackProbeSize));
184 if (CGM.getCodeGenOpts().NoStackArgProbe)
185 Fn->addFnAttr("no-stack-arg-probe");
186 }
187}
188
189/// Create an OpenCL kernel for an enqueued block.
190///
191/// The kernel has the same function type as the block invoke function. Its
192/// name is the name of the block invoke function postfixed with "_kernel".
193/// It simply calls the block invoke function then returns.
195 CodeGenFunction &CGF, llvm::Function *Invoke, llvm::Type *BlockTy) const {
196 auto *InvokeFT = Invoke->getFunctionType();
197 auto &C = CGF.getLLVMContext();
198 std::string Name = Invoke->getName().str() + "_kernel";
199 auto *FT = llvm::FunctionType::get(llvm::Type::getVoidTy(C),
200 InvokeFT->params(), false);
201 auto *F = llvm::Function::Create(FT, llvm::GlobalValue::ExternalLinkage, Name,
202 &CGF.CGM.getModule());
203 llvm::CallingConv::ID KernelCC =
205 F->setCallingConv(KernelCC);
206
207 llvm::AttrBuilder KernelAttrs(C);
208
209 // FIXME: This is missing setTargetAttributes
211 F->addFnAttrs(KernelAttrs);
212
213 auto IP = CGF.Builder.saveIP();
214 auto *BB = llvm::BasicBlock::Create(C, "entry", F);
215 auto &Builder = CGF.Builder;
216 Builder.SetInsertPoint(BB);
217 llvm::SmallVector<llvm::Value *, 2> Args(llvm::make_pointer_range(F->args()));
218 llvm::CallInst *Call = Builder.CreateCall(Invoke, Args);
219 Call->setCallingConv(Invoke->getCallingConv());
220
221 Builder.CreateRetVoid();
222 Builder.restoreIP(IP);
223 return F;
224}
225
227 const TargetInfo::BranchProtectionInfo &BPI, llvm::Function &F) {
228 // Called on already created and initialized function where attributes already
229 // set from command line attributes but some might need to be removed as the
230 // actual BPI is different.
232 F.addFnAttr("sign-return-address", BPI.getSignReturnAddrStr());
233 F.addFnAttr("sign-return-address-key", BPI.getSignKeyStr());
234 } else {
235 if (F.hasFnAttribute("sign-return-address"))
236 F.removeFnAttr("sign-return-address");
237 if (F.hasFnAttribute("sign-return-address-key"))
238 F.removeFnAttr("sign-return-address-key");
239 }
240
241 auto AddRemoveAttributeAsSet = [&](bool Set, const StringRef &ModAttr) {
242 if (Set)
243 F.addFnAttr(ModAttr);
244 else if (F.hasFnAttribute(ModAttr))
245 F.removeFnAttr(ModAttr);
246 };
247
248 AddRemoveAttributeAsSet(BPI.BranchTargetEnforcement,
249 "branch-target-enforcement");
250 AddRemoveAttributeAsSet(BPI.BranchProtectionPAuthLR,
251 "branch-protection-pauth-lr");
252 AddRemoveAttributeAsSet(BPI.GuardedControlStack, "guarded-control-stack");
253}
254
256 const TargetInfo::BranchProtectionInfo &BPI, llvm::AttrBuilder &FuncAttrs) {
257 // Only used for initializing attributes in the AttrBuilder, which will not
258 // contain any of these attributes so no need to remove anything.
260 FuncAttrs.addAttribute("sign-return-address", BPI.getSignReturnAddrStr());
261 FuncAttrs.addAttribute("sign-return-address-key", BPI.getSignKeyStr());
262 }
264 FuncAttrs.addAttribute("branch-target-enforcement");
266 FuncAttrs.addAttribute("branch-protection-pauth-lr");
267 if (BPI.GuardedControlStack)
268 FuncAttrs.addAttribute("guarded-control-stack");
269}
270
272 const PointerAuthOptions &Opts, llvm::Function &F) {
273 auto UpdateAttr = [&F](bool AttrShouldExist, StringRef AttrName) {
274 if (AttrShouldExist && !F.hasFnAttribute(AttrName))
275 F.addFnAttr(AttrName);
276 if (!AttrShouldExist && F.hasFnAttribute(AttrName))
277 F.removeFnAttr(AttrName);
278 };
279 UpdateAttr(Opts.ReturnAddresses, "ptrauth-returns");
280 UpdateAttr((bool)Opts.FunctionPointers, "ptrauth-calls");
281 UpdateAttr(Opts.AuthTraps, "ptrauth-auth-traps");
282 UpdateAttr(Opts.IndirectGotos, "ptrauth-indirect-gotos");
283 UpdateAttr(Opts.AArch64JumpTableHardening, "aarch64-jump-table-hardening");
284}
285
287 const PointerAuthOptions &Opts, llvm::AttrBuilder &FuncAttrs) {
288 if (Opts.ReturnAddresses)
289 FuncAttrs.addAttribute("ptrauth-returns");
290 if (Opts.FunctionPointers)
291 FuncAttrs.addAttribute("ptrauth-calls");
292 if (Opts.AuthTraps)
293 FuncAttrs.addAttribute("ptrauth-auth-traps");
294 if (Opts.IndirectGotos)
295 FuncAttrs.addAttribute("ptrauth-indirect-gotos");
297 FuncAttrs.addAttribute("aarch64-jump-table-hardening");
298}
299
300namespace {
301class DefaultTargetCodeGenInfo : public TargetCodeGenInfo {
302public:
303 DefaultTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT)
304 : TargetCodeGenInfo(std::make_unique<DefaultABIInfo>(CGT)) {}
305};
306} // namespace
307
308std::unique_ptr<TargetCodeGenInfo>
310 return std::make_unique<DefaultTargetCodeGenInfo>(CGM.getTypes());
311}
const Decl * D
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Definition: CharUnits.h:185
unsigned getInAllocaFieldIndex() const
llvm::StructType * getCoerceAndExpandType() const
unsigned getIndirectAddrSpace() const
@ Extend
Extend - Valid only for integer argument types.
@ Ignore
Ignore - Ignore the argument (treat as void).
@ IndirectAliased
IndirectAliased - Similar to Indirect, but the pointer may be to an object that is otherwise referenc...
@ Expand
Expand - Only valid for aggregate argument types.
@ TargetSpecific
TargetSpecific - Some argument types are passed as target specific types such as RISC-V's tuple type,...
@ InAlloca
InAlloca - Pass the argument directly using the LLVM inalloca attribute.
@ Indirect
Indirect - Pass the argument indirectly via a hidden pointer with the specified alignment (0 indicate...
@ CoerceAndExpand
CoerceAndExpand - Only valid for aggregate argument types.
@ Direct
Direct - Pass the argument directly using the normal converted LLVM type, or by coercing to another s...
llvm::Type * getCoerceToType() const
CharUnits getIndirectAlign() const
Address CreateAddrSpaceCast(Address Addr, llvm::Type *Ty, llvm::Type *ElementTy, const llvm::Twine &Name="")
Definition: CGBuilder.h:193
CallArgList - Type for representing both the value and type of arguments in a call.
Definition: CGCall.h:274
CodeGenFunction - This class organizes the per-function state that is used while generating LLVM code...
CodeGenTypes & getTypes() const
llvm::LLVMContext & getLLVMContext()
This class organizes the cross-function state that is used while generating LLVM code.
llvm::Module & getModule() const
const LangOptions & getLangOpts() const
const CodeGenOptions & getCodeGenOpts() const
void addDefaultFunctionDefinitionAttributes(llvm::AttrBuilder &attrs)
Like the overload taking a Function &, but intended specifically for frontends that want to build on ...
Definition: CGCall.cpp:2236
This class organizes the cross-module state that is used while lowering AST types to LLVM types.
Definition: CodeGenTypes.h:54
unsigned ClangCallConvToLLVMCallConv(CallingConv CC)
Convert clang calling convention to LLVM callilng convention.
Definition: CGCall.cpp:52
DefaultABIInfo - The default implementation for ABI specific details.
Definition: ABIInfoImpl.h:21
TargetCodeGenInfo - This class organizes various target-specific codegeneration issues,...
Definition: TargetInfo.h:47
virtual unsigned getDeviceKernelCallingConv() const
Get LLVM calling convention for device kernels.
Definition: TargetInfo.cpp:113
virtual unsigned getSizeOfUnwindException() const
Determines the size of struct _Unwind_Exception on this platform, in 8-bit units.
Definition: TargetInfo.cpp:84
virtual void setOCLKernelStubCallingConvention(const FunctionType *&FT) const
Definition: TargetInfo.cpp:130
virtual void getDependentLibraryOption(llvm::StringRef Lib, llvm::SmallString< 24 > &Opt) const
Gets the linker options necessary to link a dependent library on this platform.
Definition: TargetInfo.cpp:104
Address performAddrSpaceCast(CodeGen::CodeGenFunction &CGF, Address Addr, LangAS SrcAddr, llvm::Type *DestTy, bool IsNonNull=false) const
virtual llvm::SyncScope::ID getLLVMSyncScopeID(const LangOptions &LangOpts, SyncScope Scope, llvm::AtomicOrdering Ordering, llvm::LLVMContext &Ctx) const
Get the syncscope used in LLVM IR.
Definition: TargetInfo.cpp:171
static void setBranchProtectionFnAttributes(const TargetInfo::BranchProtectionInfo &BPI, llvm::Function &F)
Definition: TargetInfo.cpp:226
const T & getABIInfo() const
Definition: TargetInfo.h:57
static void initPointerAuthFnAttributes(const PointerAuthOptions &Opts, llvm::AttrBuilder &FuncAttrs)
Definition: TargetInfo.cpp:286
static void setPointerAuthFnAttributes(const PointerAuthOptions &Opts, llvm::Function &F)
Definition: TargetInfo.cpp:271
virtual LangAS getGlobalVarAddressSpace(CodeGenModule &CGM, const VarDecl *D) const
Get target favored AST address space of a global variable for languages other than OpenCL and CUDA.
Definition: TargetInfo.cpp:141
void addStackProbeTargetAttributes(const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &CGM) const
Definition: TargetInfo.cpp:178
virtual llvm::Constant * getNullPointer(const CodeGen::CodeGenModule &CGM, llvm::PointerType *T, QualType QT) const
Get target specific null pointer.
Definition: TargetInfo.cpp:136
static void initBranchProtectionFnAttributes(const TargetInfo::BranchProtectionInfo &BPI, llvm::AttrBuilder &FuncAttrs)
Definition: TargetInfo.cpp:255
TargetCodeGenInfo(std::unique_ptr< ABIInfo > Info)
Definition: TargetInfo.cpp:77
virtual llvm::Value * createEnqueuedBlockKernel(CodeGenFunction &CGF, llvm::Function *BlockInvokeFunc, llvm::Type *BlockTy) const
Create an OpenCL kernel for an enqueued block.
Definition: TargetInfo.cpp:194
virtual bool isNoProtoCallVariadic(const CodeGen::CallArgList &args, const FunctionNoProtoType *fnType) const
Determine whether a call to an unprototyped functions under the given calling convention should use t...
Definition: TargetInfo.cpp:94
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:86
Represents a K&R-style 'int foo()' function, which has no information available about its arguments.
Definition: TypeBase.h:4860
ExtInfo withCallingConv(CallingConv cc) const
Definition: TypeBase.h:4701
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition: TypeBase.h:4478
ExtInfo getExtInfo() const
Definition: TypeBase.h:4834
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
Definition: LangOptions.h:434
A (possibly-)qualified type.
Definition: TypeBase.h:937
Scope - A scope is a transient data structure that is used while parsing the program.
Definition: Scope.h:41
LangOptions::SignReturnAddressScopeKind SignReturnAddr
Definition: TargetInfo.h:1443
const char * getSignReturnAddrStr() const
Definition: TargetInfo.h:1449
Represents a variable declaration or definition.
Definition: Decl.h:925
std::unique_ptr< TargetCodeGenInfo > createDefaultTargetCodeGenInfo(CodeGenModule &CGM)
Definition: TargetInfo.cpp:309
The JSON file list parser is used to communicate input to InstallAPI.
@ OpenCL
Definition: LangStandard.h:65
LangAS
Defines the address space values used by the address space qualifier of QualType.
Definition: AddressSpaces.h:25
const FunctionProtoType * T
SyncScope
Defines sync scope values used internally by clang.
Definition: SyncScope.h:42
@ CC_DeviceKernel
Definition: Specifiers.h:292
@ CC_C
Definition: Specifiers.h:279
bool ReturnAddresses
Should return addresses be authenticated?
bool AArch64JumpTableHardening
Use hardened lowering for jump-table dispatch?
PointerAuthSchema FunctionPointers
The ABI for C function pointers.
bool AuthTraps
Do authentication failures cause a trap?
bool IndirectGotos
Do indirect goto label addresses need to be authenticated?