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/Function.h" 23 #include "llvm/IR/Type.h" 24 #include "llvm/Support/raw_ostream.h" 25 26 using namespace clang; 27 using namespace CodeGen; 28 29 LLVM_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 } 67 OS << ")\n"; 68 } 69 70 TargetCodeGenInfo::TargetCodeGenInfo(std::unique_ptr<ABIInfo> Info) 71 : Info(std::move(Info)) {} 72 73 TargetCodeGenInfo::~TargetCodeGenInfo() = default; 74 75 // If someone can figure out a general rule for this, that would be great. 76 // It's probably just doomed to be platform-dependent, though. 77 unsigned TargetCodeGenInfo::getSizeOfUnwindException() const { 78 // Verified for: 79 // x86-64 FreeBSD, Linux, Darwin 80 // x86-32 FreeBSD, Linux, Darwin 81 // PowerPC Linux 82 // ARM Darwin (*not* EABI) 83 // AArch64 Linux 84 return 32; 85 } 86 87 bool TargetCodeGenInfo::isNoProtoCallVariadic(const CallArgList &args, 88 const FunctionNoProtoType *fnType) const { 89 // The following conventions are known to require this to be false: 90 // x86_stdcall 91 // MIPS 92 // For everything else, we just prefer false unless we opt out. 93 return false; 94 } 95 96 void 97 TargetCodeGenInfo::getDependentLibraryOption(llvm::StringRef Lib, 98 llvm::SmallString<24> &Opt) const { 99 // This assumes the user is passing a library name like "rt" instead of a 100 // filename like "librt.a/so", and that they don't care whether it's static or 101 // dynamic. 102 Opt = "-l"; 103 Opt += Lib; 104 } 105 106 unsigned TargetCodeGenInfo::getOpenCLKernelCallingConv() const { 107 // OpenCL kernels are called via an explicit runtime API with arguments 108 // set with clSetKernelArg(), not as normal sub-functions. 109 // Return SPIR_KERNEL by default as the kernel calling convention to 110 // ensure the fingerprint is fixed such way that each OpenCL argument 111 // gets one matching argument in the produced kernel function argument 112 // list to enable feasible implementation of clSetKernelArg() with 113 // aggregates etc. In case we would use the default C calling conv here, 114 // clSetKernelArg() might break depending on the target-specific 115 // conventions; different targets might split structs passed as values 116 // to multiple function arguments etc. 117 return llvm::CallingConv::SPIR_KERNEL; 118 } 119 120 llvm::Constant *TargetCodeGenInfo::getNullPointer(const CodeGen::CodeGenModule &CGM, 121 llvm::PointerType *T, QualType QT) const { 122 return llvm::ConstantPointerNull::get(T); 123 } 124 125 LangAS TargetCodeGenInfo::getGlobalVarAddressSpace(CodeGenModule &CGM, 126 const VarDecl *D) const { 127 assert(!CGM.getLangOpts().OpenCL && 128 !(CGM.getLangOpts().CUDA && CGM.getLangOpts().CUDAIsDevice) && 129 "Address space agnostic languages only"); 130 return D ? D->getType().getAddressSpace() : LangAS::Default; 131 } 132 133 llvm::Value *TargetCodeGenInfo::performAddrSpaceCast( 134 CodeGen::CodeGenFunction &CGF, llvm::Value *Src, LangAS SrcAddr, 135 LangAS DestAddr, llvm::Type *DestTy, bool isNonNull) const { 136 // Since target may map different address spaces in AST to the same address 137 // space, an address space conversion may end up as a bitcast. 138 if (auto *C = dyn_cast<llvm::Constant>(Src)) 139 return performAddrSpaceCast(CGF.CGM, C, SrcAddr, DestAddr, DestTy); 140 // Try to preserve the source's name to make IR more readable. 141 return CGF.Builder.CreateAddrSpaceCast( 142 Src, DestTy, Src->hasName() ? Src->getName() + ".ascast" : ""); 143 } 144 145 llvm::Constant * 146 TargetCodeGenInfo::performAddrSpaceCast(CodeGenModule &CGM, llvm::Constant *Src, 147 LangAS SrcAddr, LangAS DestAddr, 148 llvm::Type *DestTy) const { 149 // Since target may map different address spaces in AST to the same address 150 // space, an address space conversion may end up as a bitcast. 151 return llvm::ConstantExpr::getPointerCast(Src, DestTy); 152 } 153 154 llvm::SyncScope::ID 155 TargetCodeGenInfo::getLLVMSyncScopeID(const LangOptions &LangOpts, 156 SyncScope Scope, 157 llvm::AtomicOrdering Ordering, 158 llvm::LLVMContext &Ctx) const { 159 return Ctx.getOrInsertSyncScopeID(""); /* default sync scope */ 160 } 161 162 void TargetCodeGenInfo::addStackProbeTargetAttributes( 163 const Decl *D, llvm::GlobalValue *GV, CodeGen::CodeGenModule &CGM) const { 164 if (llvm::Function *Fn = dyn_cast_or_null<llvm::Function>(GV)) { 165 if (CGM.getCodeGenOpts().StackProbeSize != 4096) 166 Fn->addFnAttr("stack-probe-size", 167 llvm::utostr(CGM.getCodeGenOpts().StackProbeSize)); 168 if (CGM.getCodeGenOpts().NoStackArgProbe) 169 Fn->addFnAttr("no-stack-arg-probe"); 170 } 171 } 172 173 /// Create an OpenCL kernel for an enqueued block. 174 /// 175 /// The kernel has the same function type as the block invoke function. Its 176 /// name is the name of the block invoke function postfixed with "_kernel". 177 /// It simply calls the block invoke function then returns. 178 llvm::Value *TargetCodeGenInfo::createEnqueuedBlockKernel( 179 CodeGenFunction &CGF, llvm::Function *Invoke, llvm::Type *BlockTy) const { 180 auto *InvokeFT = Invoke->getFunctionType(); 181 auto &C = CGF.getLLVMContext(); 182 std::string Name = Invoke->getName().str() + "_kernel"; 183 auto *FT = llvm::FunctionType::get(llvm::Type::getVoidTy(C), 184 InvokeFT->params(), false); 185 auto *F = llvm::Function::Create(FT, llvm::GlobalValue::ExternalLinkage, Name, 186 &CGF.CGM.getModule()); 187 llvm::CallingConv::ID KernelCC = 188 CGF.getTypes().ClangCallConvToLLVMCallConv(CallingConv::CC_OpenCLKernel); 189 F->setCallingConv(KernelCC); 190 191 llvm::AttrBuilder KernelAttrs(C); 192 193 // FIXME: This is missing setTargetAttributes 194 CGF.CGM.addDefaultFunctionDefinitionAttributes(KernelAttrs); 195 F->addFnAttrs(KernelAttrs); 196 197 auto IP = CGF.Builder.saveIP(); 198 auto *BB = llvm::BasicBlock::Create(C, "entry", F); 199 auto &Builder = CGF.Builder; 200 Builder.SetInsertPoint(BB); 201 llvm::SmallVector<llvm::Value *, 2> Args(llvm::make_pointer_range(F->args())); 202 llvm::CallInst *Call = Builder.CreateCall(Invoke, Args); 203 Call->setCallingConv(Invoke->getCallingConv()); 204 205 Builder.CreateRetVoid(); 206 Builder.restoreIP(IP); 207 return F; 208 } 209 210 void TargetCodeGenInfo::setBranchProtectionFnAttributes( 211 const TargetInfo::BranchProtectionInfo &BPI, llvm::Function &F) { 212 // Called on already created and initialized function where attributes already 213 // set from command line attributes but some might need to be removed as the 214 // actual BPI is different. 215 if (BPI.SignReturnAddr != LangOptions::SignReturnAddressScopeKind::None) { 216 F.addFnAttr("sign-return-address", BPI.getSignReturnAddrStr()); 217 F.addFnAttr("sign-return-address-key", BPI.getSignKeyStr()); 218 } else { 219 if (F.hasFnAttribute("sign-return-address")) 220 F.removeFnAttr("sign-return-address"); 221 if (F.hasFnAttribute("sign-return-address-key")) 222 F.removeFnAttr("sign-return-address-key"); 223 } 224 225 auto AddRemoveAttributeAsSet = [&](bool Set, const StringRef &ModAttr) { 226 if (Set) 227 F.addFnAttr(ModAttr); 228 else if (F.hasFnAttribute(ModAttr)) 229 F.removeFnAttr(ModAttr); 230 }; 231 232 AddRemoveAttributeAsSet(BPI.BranchTargetEnforcement, 233 "branch-target-enforcement"); 234 AddRemoveAttributeAsSet(BPI.BranchProtectionPAuthLR, 235 "branch-protection-pauth-lr"); 236 AddRemoveAttributeAsSet(BPI.GuardedControlStack, "guarded-control-stack"); 237 } 238 239 void TargetCodeGenInfo::initBranchProtectionFnAttributes( 240 const TargetInfo::BranchProtectionInfo &BPI, llvm::AttrBuilder &FuncAttrs) { 241 // Only used for initializing attributes in the AttrBuilder, which will not 242 // contain any of these attributes so no need to remove anything. 243 if (BPI.SignReturnAddr != LangOptions::SignReturnAddressScopeKind::None) { 244 FuncAttrs.addAttribute("sign-return-address", BPI.getSignReturnAddrStr()); 245 FuncAttrs.addAttribute("sign-return-address-key", BPI.getSignKeyStr()); 246 } 247 if (BPI.BranchTargetEnforcement) 248 FuncAttrs.addAttribute("branch-target-enforcement"); 249 if (BPI.BranchProtectionPAuthLR) 250 FuncAttrs.addAttribute("branch-protection-pauth-lr"); 251 if (BPI.GuardedControlStack) 252 FuncAttrs.addAttribute("guarded-control-stack"); 253 } 254 255 namespace { 256 class DefaultTargetCodeGenInfo : public TargetCodeGenInfo { 257 public: 258 DefaultTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT) 259 : TargetCodeGenInfo(std::make_unique<DefaultABIInfo>(CGT)) {} 260 }; 261 } // namespace 262 263 std::unique_ptr<TargetCodeGenInfo> 264 CodeGen::createDefaultTargetCodeGenInfo(CodeGenModule &CGM) { 265 return std::make_unique<DefaultTargetCodeGenInfo>(CGM.getTypes()); 266 } 267