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