23#include "llvm/ADT/StringRef.h"
24#include "llvm/Frontend/Offloading/Utility.h"
25#include "llvm/IR/BasicBlock.h"
26#include "llvm/IR/Constants.h"
27#include "llvm/IR/DerivedTypes.h"
28#include "llvm/IR/GlobalValue.h"
29#include "llvm/IR/ReplaceConstant.h"
30#include "llvm/ProfileData/InstrProf.h"
31#include "llvm/Support/Format.h"
32#include "llvm/Support/MD5.h"
33#include "llvm/Support/VirtualFileSystem.h"
39constexpr unsigned CudaFatMagic = 0x466243b1;
40constexpr unsigned HIPFatMagic = 0x48495046;
48 llvm::IntegerType *IntTy, *SizeTy;
50 llvm::PointerType *PtrTy;
53 llvm::LLVMContext &Context;
55 llvm::Module &TheModule;
58 llvm::Function *Kernel;
61 llvm::SmallVector<KernelInfo, 16> EmittedKernels;
65 llvm::DenseMap<StringRef, llvm::GlobalValue *> KernelHandles;
67 llvm::DenseMap<llvm::GlobalValue *, llvm::Function *> KernelStubs;
69 llvm::GlobalVariable *Var;
73 llvm::SmallVector<VarInfo, 16> DeviceVars;
77 llvm::GlobalVariable *GpuBinaryHandle =
nullptr;
82 llvm::GlobalVariable *OffloadProfShadow =
nullptr;
84 llvm::GlobalVariable *OffloadProfVersionShadow =
nullptr;
85 struct OffloadProfSectionShadowInfo {
86 llvm::GlobalVariable *Shadow;
87 std::string DeviceName;
89 llvm::SmallVector<OffloadProfSectionShadowInfo, 16> OffloadProfSectionShadows;
91 bool RelocatableDeviceCode;
93 std::unique_ptr<MangleContext> DeviceMC;
95 llvm::FunctionCallee getSetupArgumentFn()
const;
96 llvm::FunctionCallee getLaunchFn()
const;
98 llvm::FunctionType *getRegisterGlobalsFnTy()
const;
99 llvm::FunctionType *getCallbackFnTy()
const;
100 llvm::FunctionType *getRegisterLinkedBinaryFnTy()
const;
101 std::string addPrefixToName(StringRef FuncName)
const;
102 std::string addUnderscoredPrefixToName(StringRef FuncName)
const;
105 llvm::Function *makeRegisterGlobalsFn();
110 llvm::Constant *makeConstantString(
const std::string &Str,
111 const std::string &Name =
"") {
112 return CGM.GetAddrOfConstantCString(Str, Name).getPointer();
118 llvm::Constant *makeConstantArray(StringRef Str,
120 StringRef SectionName =
"",
121 unsigned Alignment = 0,
122 bool AddNull =
false) {
123 llvm::Constant *
Value =
124 llvm::ConstantDataArray::getString(Context, Str, AddNull);
125 auto *GV =
new llvm::GlobalVariable(
126 TheModule,
Value->getType(),
true,
127 llvm::GlobalValue::PrivateLinkage,
Value, Name);
128 if (!SectionName.empty()) {
129 GV->setSection(SectionName);
132 GV->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::None);
135 GV->setAlignment(llvm::Align(Alignment));
140 llvm::Function *makeDummyFunction(llvm::FunctionType *FnTy) {
141 assert(FnTy->getReturnType()->isVoidTy() &&
142 "Can only generate dummy functions returning void!");
143 llvm::Function *DummyFunc = llvm::Function::Create(
144 FnTy, llvm::GlobalValue::InternalLinkage,
"dummy", &TheModule);
146 llvm::BasicBlock *DummyBlock =
147 llvm::BasicBlock::Create(Context,
"", DummyFunc);
148 CGBuilderTy FuncBuilder(CGM, Context);
149 FuncBuilder.SetInsertPoint(DummyBlock);
150 FuncBuilder.CreateRetVoid();
155 Address prepareKernelArgs(CodeGenFunction &CGF, FunctionArgList &Args);
156 Address prepareKernelArgsLLVMOffload(CodeGenFunction &CGF,
157 FunctionArgList &Args);
158 void emitDeviceStubBodyLegacy(CodeGenFunction &CGF, FunctionArgList &Args);
159 void emitDeviceStubBodyNew(CodeGenFunction &CGF, FunctionArgList &Args);
160 std::string getDeviceSideName(
const NamedDecl *ND)
override;
162 void registerDeviceVar(
const VarDecl *VD, llvm::GlobalVariable &Var,
164 DeviceVars.push_back({&Var,
166 {DeviceVarFlags::Variable, Extern,
Constant,
167 VD->hasAttr<HIPManagedAttr>(),
170 void registerDeviceSurf(
const VarDecl *VD, llvm::GlobalVariable &Var,
171 bool Extern,
int Type) {
172 DeviceVars.push_back({&Var,
174 {DeviceVarFlags::Surface, Extern,
false,
178 void registerDeviceTex(
const VarDecl *VD, llvm::GlobalVariable &Var,
179 bool Extern,
int Type,
bool Normalized) {
180 DeviceVars.push_back({&Var,
182 {DeviceVarFlags::Texture, Extern,
false,
183 false, Normalized,
Type}});
187 llvm::Function *makeModuleCtorFunction();
189 llvm::Function *makeModuleDtorFunction();
191 void transformManagedVars();
193 void createOffloadingEntries();
201 void emitOffloadProfilingSections();
204 CGNVCUDARuntime(CodeGenModule &CGM);
206 llvm::GlobalValue *getKernelHandle(llvm::Function *F, GlobalDecl GD)
override;
207 llvm::Function *getKernelStub(llvm::GlobalValue *Handle)
override {
208 auto Loc = KernelStubs.find(Handle);
209 assert(Loc != KernelStubs.end());
212 void emitDeviceStub(CodeGenFunction &CGF, FunctionArgList &Args)
override;
213 void handleVarRegistration(
const VarDecl *VD,
214 llvm::GlobalVariable &Var)
override;
216 internalizeDeviceSideVar(
const VarDecl *D,
217 llvm::GlobalValue::LinkageTypes &
Linkage)
override;
219 llvm::Function *finalizeModule()
override;
224std::string CGNVCUDARuntime::addPrefixToName(StringRef FuncName)
const {
225 return (Prefix + FuncName).str();
228CGNVCUDARuntime::addUnderscoredPrefixToName(StringRef FuncName)
const {
229 return (
"__" + Prefix + FuncName).str();
239 return std::unique_ptr<MangleContext>(
248CGNVCUDARuntime::CGNVCUDARuntime(CodeGenModule &CGM)
249 : CGCUDARuntime(CGM), Context(CGM.getLLVMContext()),
250 TheModule(CGM.getModule()),
251 RelocatableDeviceCode(CGM.getLangOpts().GPURelocatableDeviceCode),
266llvm::FunctionCallee CGNVCUDARuntime::getSetupArgumentFn()
const {
268 llvm::Type *Params[] = {PtrTy, SizeTy, SizeTy};
270 llvm::FunctionType::get(IntTy, Params,
false),
271 addPrefixToName(
"SetupArgument"));
274llvm::FunctionCallee CGNVCUDARuntime::getLaunchFn()
const {
278 llvm::FunctionType::get(IntTy, PtrTy,
false),
"hipLaunchByPtr");
285llvm::FunctionType *CGNVCUDARuntime::getRegisterGlobalsFnTy()
const {
286 return llvm::FunctionType::get(VoidTy, PtrTy,
false);
289llvm::FunctionType *CGNVCUDARuntime::getCallbackFnTy()
const {
290 return llvm::FunctionType::get(VoidTy, PtrTy,
false);
293llvm::FunctionType *CGNVCUDARuntime::getRegisterLinkedBinaryFnTy()
const {
294 llvm::Type *Params[] = {llvm::PointerType::getUnqual(Context), PtrTy, PtrTy,
295 llvm::PointerType::getUnqual(Context)};
296 return llvm::FunctionType::get(VoidTy, Params,
false);
299std::string CGNVCUDARuntime::getDeviceSideName(
const NamedDecl *ND) {
302 if (
auto *FD = dyn_cast<FunctionDecl>(ND))
303 GD = GlobalDecl(FD, KernelReferenceKind::Kernel);
306 std::string DeviceSideName;
313 SmallString<256> Buffer;
314 llvm::raw_svector_ostream
Out(Buffer);
316 DeviceSideName = std::string(
Out.str());
323 SmallString<256> Buffer;
324 llvm::raw_svector_ostream
Out(Buffer);
325 Out << DeviceSideName;
327 DeviceSideName = std::string(
Out.str());
329 return DeviceSideName;
332void CGNVCUDARuntime::emitDeviceStub(CodeGenFunction &CGF,
333 FunctionArgList &Args) {
336 dyn_cast<llvm::GlobalVariable>(KernelHandles[CGF.
CurFn->getName()])) {
337 GV->setLinkage(CGF.
CurFn->getLinkage());
338 GV->setInitializer(CGF.
CurFn);
342 CudaFeature::CUDA_USES_NEW_LAUNCH) ||
345 emitDeviceStubBodyNew(CGF, Args);
347 emitDeviceStubBodyLegacy(CGF, Args);
355Address CGNVCUDARuntime::prepareKernelArgsLLVMOffload(CodeGenFunction &CGF,
356 FunctionArgList &Args) {
357 SmallVector<llvm::Type *> KernelLaunchParamsTypes;
359 auto *Int64Ty = CGF.
Builder.getInt64Ty();
360 KernelLaunchParamsTypes.push_back(PtrTy);
361 KernelLaunchParamsTypes.push_back(Int64Ty);
362 KernelLaunchParamsTypes.push_back(PtrTy);
364 llvm::StructType *KernelLaunchParamsTy =
365 llvm::StructType::create(KernelLaunchParamsTypes);
368 "kernel_launch_params");
371 llvm::ConstantInt::get(SizeTy, std::max<size_t>(1, Args.size())));
374 llvm::ConstantInt::get(SizeTy, std::max<size_t>(1, Args.size())));
383 for (
unsigned i = 0; i < Args.size(); ++i) {
385 llvm::Value *VoidVarPtr = CGF.
Builder.CreatePointerCast(VarPtr, PtrTy);
387 VoidVarPtr, CGF.
Builder.CreateConstGEP1_32(
393 llvm::ConstantInt::get(SizeTy, ArgSize),
394 CGF.
Builder.CreateConstGEP1_32(SizeTy,
398 return KernelLaunchParams;
401Address CGNVCUDARuntime::prepareKernelArgs(CodeGenFunction &CGF,
402 FunctionArgList &Args) {
408 llvm::ConstantInt::get(SizeTy, std::max<size_t>(1, Args.size())));
410 for (
unsigned i = 0; i < Args.size(); ++i) {
412 llvm::Value *VoidVarPtr = CGF.
Builder.CreatePointerCast(VarPtr, PtrTy);
414 VoidVarPtr, CGF.
Builder.CreateConstGEP1_32(
422void CGNVCUDARuntime::emitDeviceStubBodyNew(CodeGenFunction &CGF,
423 FunctionArgList &Args) {
424 bool UsesLLVMOffloading = CGF.
getLangOpts().OffloadViaLLVM;
426 Address KernelArgs = UsesLLVMOffloading
427 ? prepareKernelArgsLLVMOffload(CGF, Args)
428 : prepareKernelArgs(CGF, Args);
442 TranslationUnitDecl *TUDecl = CGM.
getContext().getTranslationUnitDecl();
444 std::string KernelLaunchAPI =
"LaunchKernel";
446 LangOptions::GPUDefaultStreamKind::PerThread) {
448 KernelLaunchAPI = KernelLaunchAPI +
"_spt";
450 KernelLaunchAPI = KernelLaunchAPI +
"_ptsz";
452 auto LaunchKernelName = addPrefixToName(KernelLaunchAPI);
453 const IdentifierInfo &cudaLaunchKernelII =
455 FunctionDecl *cudaLaunchKernelFD =
nullptr;
457 if (FunctionDecl *FD = dyn_cast<FunctionDecl>(
Result))
458 cudaLaunchKernelFD = FD;
461 if (cudaLaunchKernelFD ==
nullptr) {
463 "Can't find declaration for " + LaunchKernelName);
467 ParmVarDecl *GridDimParam = cudaLaunchKernelFD->
getParamDecl(1);
468 QualType Dim3Ty = GridDimParam->
getType();
478 llvm::FunctionType::get(IntTy,
484 addUnderscoredPrefixToName(
"PopCallConfiguration"));
493 CGF.
Builder.CreatePointerCast(KernelHandles[CGF.
CurFn->getName()], PtrTy);
494 CallArgList LaunchKernelArgs;
506 QualType QT = cudaLaunchKernelFD->
getType();
511 const CGFunctionInfo &FI =
513 llvm::FunctionCallee cudaLaunchKernelFn =
523 llvm::Function *KernelFunction = llvm::cast<llvm::Function>(
Kernel);
524 std::string GlobalVarName = (KernelFunction->getName() +
".id").str();
526 llvm::GlobalVariable *HandleVar =
527 CGM.
getModule().getNamedGlobal(GlobalVarName);
529 HandleVar =
new llvm::GlobalVariable(
531 false, KernelFunction->getLinkage(),
532 llvm::ConstantInt::get(CGM.
Int8Ty, 0), GlobalVarName);
533 HandleVar->setDSOLocal(KernelFunction->isDSOLocal());
534 HandleVar->setVisibility(KernelFunction->getVisibility());
535 if (KernelFunction->hasComdat())
536 HandleVar->setComdat(CGM.
getModule().getOrInsertComdat(GlobalVarName));
549void CGNVCUDARuntime::emitDeviceStubBodyLegacy(CodeGenFunction &CGF,
550 FunctionArgList &Args) {
552 llvm::FunctionCallee cudaSetupArgFn = getSetupArgumentFn();
555 for (
const VarDecl *A : Args) {
557 Offset = Offset.
alignTo(TInfo.Align);
558 llvm::Value *Args[] = {
561 llvm::ConstantInt::get(SizeTy, TInfo.Width.getQuantity()),
562 llvm::ConstantInt::get(SizeTy, Offset.
getQuantity()),
565 llvm::Constant *
Zero = llvm::ConstantInt::get(IntTy, 0);
566 llvm::Value *CBZero = CGF.
Builder.CreateICmpEQ(CB,
Zero);
568 CGF.
Builder.CreateCondBr(CBZero, NextBlock, EndBlock);
570 Offset += TInfo.Width;
574 llvm::FunctionCallee cudaLaunchFn = getLaunchFn();
576 CGF.
Builder.CreatePointerCast(KernelHandles[CGF.
CurFn->getName()], PtrTy);
586 llvm::GlobalVariable *ManagedVar) {
588 for (
auto &&VarUse : Var->uses()) {
589 WorkList.push_back({VarUse.getUser()});
591 while (!WorkList.empty()) {
592 auto &&WorkItem = WorkList.pop_back_val();
593 auto *
U = WorkItem.back();
595 for (
auto &&UU :
U->uses()) {
596 WorkItem.push_back(UU.getUser());
597 WorkList.push_back(WorkItem);
602 if (
auto *I = dyn_cast<llvm::Instruction>(
U)) {
603 llvm::Value *OldV = Var;
604 llvm::Instruction *NewV =
605 new llvm::LoadInst(Var->getType(), ManagedVar,
"ld.managed",
false,
606 Var->getAlign().valueOrOne(), I->getIterator());
610 for (
auto &&Op : WorkItem) {
612 auto *NewInst = CE->getAsInstruction();
613 NewInst->insertBefore(*I->getParent(), I->getIterator());
614 NewInst->replaceUsesOfWith(OldV, NewV);
618 I->replaceUsesOfWith(OldV, NewV);
620 llvm_unreachable(
"Invalid use of managed variable");
639llvm::Function *CGNVCUDARuntime::makeRegisterGlobalsFn() {
641 if (EmittedKernels.empty() && DeviceVars.empty())
644 llvm::Function *RegisterKernelsFunc = llvm::Function::Create(
645 getRegisterGlobalsFnTy(), llvm::GlobalValue::InternalLinkage,
646 addUnderscoredPrefixToName(
"_register_globals"), &TheModule);
647 llvm::BasicBlock *EntryBB =
648 llvm::BasicBlock::Create(Context,
"entry", RegisterKernelsFunc);
649 CGBuilderTy Builder(CGM, Context);
650 Builder.SetInsertPoint(EntryBB);
654 llvm::Type *RegisterFuncParams[] = {
655 PtrTy, PtrTy, PtrTy, PtrTy, IntTy,
656 PtrTy, PtrTy, PtrTy, PtrTy, llvm::PointerType::getUnqual(Context)};
658 llvm::FunctionType::get(IntTy, RegisterFuncParams,
false),
659 addUnderscoredPrefixToName(
"RegisterFunction"));
664 llvm::Argument &GpuBinaryHandlePtr = *RegisterKernelsFunc->arg_begin();
665 for (
auto &&I : EmittedKernels) {
666 llvm::Constant *KernelName =
668 llvm::Constant *NullPtr = llvm::ConstantPointerNull::get(PtrTy);
669 llvm::Value *Args[] = {
671 KernelHandles[I.Kernel->getName()],
674 llvm::ConstantInt::getAllOnesValue(IntTy),
679 llvm::ConstantPointerNull::get(llvm::PointerType::getUnqual(Context))};
680 Builder.CreateCall(RegisterFunc, Args);
683 llvm::Type *VarSizeTy = IntTy;
691 llvm::Type *RegisterVarParams[] = {PtrTy, PtrTy, PtrTy, PtrTy,
692 IntTy, VarSizeTy, IntTy, IntTy};
694 llvm::FunctionType::get(VoidTy, RegisterVarParams,
false),
695 addUnderscoredPrefixToName(
"RegisterVar"));
698 llvm::Type *RegisterManagedVarParams[] = {PtrTy, PtrTy, PtrTy,
699 PtrTy, VarSizeTy, IntTy};
701 llvm::FunctionType::get(VoidTy, RegisterManagedVarParams,
false),
702 addUnderscoredPrefixToName(
"RegisterManagedVar"));
706 llvm::FunctionType::get(
707 VoidTy, {PtrTy, PtrTy, PtrTy, PtrTy, IntTy, IntTy},
false),
708 addUnderscoredPrefixToName(
"RegisterSurface"));
712 llvm::FunctionType::get(
713 VoidTy, {PtrTy, PtrTy, PtrTy, PtrTy, IntTy, IntTy, IntTy},
false),
714 addUnderscoredPrefixToName(
"RegisterTexture"));
715 for (
auto &&Info : DeviceVars) {
716 llvm::GlobalVariable *Var = Info.Var;
717 assert((!Var->isDeclaration() || Info.Flags.isManaged()) &&
718 "External variables should not show up here, except HIP managed "
720 llvm::Constant *VarName = makeConstantString(getDeviceSideName(Info.D));
721 switch (Info.Flags.getKind()) {
722 case DeviceVarFlags::Variable: {
725 if (Info.Flags.isManaged()) {
726 assert(Var->getName().ends_with(
".managed") &&
727 "HIP managed variables not transformed");
728 auto *ManagedVar = CGM.
getModule().getNamedGlobal(
729 Var->getName().drop_back(StringRef(
".managed").size()));
730 llvm::Value *Args[] = {
735 llvm::ConstantInt::get(VarSizeTy, VarSize),
736 llvm::ConstantInt::get(IntTy,
737 Var->getAlign().valueOrOne().value())};
738 if (!Var->isDeclaration())
739 Builder.CreateCall(RegisterManagedVar, Args);
741 llvm::Value *Args[] = {
746 llvm::ConstantInt::get(IntTy, Info.Flags.isExtern()),
747 llvm::ConstantInt::get(VarSizeTy, VarSize),
748 llvm::ConstantInt::get(IntTy, Info.Flags.isConstant()),
749 llvm::ConstantInt::get(IntTy, 0)};
750 Builder.CreateCall(RegisterVar, Args);
754 case DeviceVarFlags::Surface:
757 {&GpuBinaryHandlePtr, Var, VarName, VarName,
758 llvm::ConstantInt::get(IntTy, Info.Flags.getSurfTexType()),
759 llvm::ConstantInt::get(IntTy, Info.Flags.isExtern())});
761 case DeviceVarFlags::Texture:
764 {&GpuBinaryHandlePtr, Var, VarName, VarName,
765 llvm::ConstantInt::get(IntTy, Info.Flags.getSurfTexType()),
766 llvm::ConstantInt::get(IntTy, Info.Flags.isNormalized()),
767 llvm::ConstantInt::get(IntTy, Info.Flags.isExtern())});
772 auto RegisterProfileShadow = [&](llvm::GlobalVariable *Shadow,
773 StringRef DeviceName) {
774 llvm::Constant *Name = makeConstantString(DeviceName.str());
775 llvm::Constant *IntZero = llvm::ConstantInt::get(IntTy, 0);
777 CGM.
getDataLayout().getTypeAllocSize(Shadow->getValueType());
778 llvm::Value *Args[] = {&GpuBinaryHandlePtr,
783 llvm::ConstantInt::get(VarSizeTy, Size),
786 Builder.CreateCall(RegisterVar, Args);
795 if (OffloadProfShadow) {
796 RegisterProfileShadow(OffloadProfShadow, OffloadProfShadow->getName());
799 llvm::FunctionType::get(VoidTy, {PtrTy},
false),
800 "__llvm_profile_offload_register_shadow_variable");
801 Builder.CreateCall(RegisterShadow, {OffloadProfShadow});
804 if (OffloadProfVersionShadow) {
805 RegisterProfileShadow(OffloadProfVersionShadow,
806 "__llvm_profile_raw_version");
808 llvm::FunctionType::get(VoidTy, {PtrTy},
false),
809 "__llvm_profile_offload_register_version_shadow_variable");
810 Builder.CreateCall(RegisterVersionShadow, {OffloadProfVersionShadow});
813 if (!OffloadProfSectionShadows.empty()) {
815 llvm::FunctionType::get(VoidTy, {PtrTy},
false),
816 "__llvm_profile_offload_register_section_shadow_variable");
817 for (
const auto &Info : OffloadProfSectionShadows) {
818 RegisterProfileShadow(Info.Shadow, Info.DeviceName);
819 Builder.CreateCall(RegisterSectionShadow, {Info.Shadow});
823 Builder.CreateRetVoid();
824 return RegisterKernelsFunc;
846llvm::Function *CGNVCUDARuntime::makeModuleCtorFunction() {
850 StringRef CudaGpuBinaryFileName =
852 if (CudaGpuBinaryFileName.empty() && !IsHIP)
854 if ((IsHIP || (IsCUDA && !RelocatableDeviceCode)) && EmittedKernels.empty() &&
859 llvm::Function *RegisterGlobalsFunc = makeRegisterGlobalsFn();
862 if (RelocatableDeviceCode && !RegisterGlobalsFunc)
863 RegisterGlobalsFunc = makeDummyFunction(getRegisterGlobalsFnTy());
867 llvm::FunctionType::get(PtrTy, PtrTy,
false),
868 addUnderscoredPrefixToName(
"RegisterFatBinary"));
870 llvm::StructType *FatbinWrapperTy =
871 llvm::StructType::get(IntTy, IntTy, PtrTy, PtrTy);
877 std::unique_ptr<llvm::MemoryBuffer> CudaGpuBinary =
nullptr;
878 if (!CudaGpuBinaryFileName.empty()) {
880 auto CudaGpuBinaryOrErr =
881 VFS->getBufferForFile(CudaGpuBinaryFileName, -1,
false);
882 if (std::error_code EC = CudaGpuBinaryOrErr.getError()) {
884 << CudaGpuBinaryFileName << EC.message();
887 CudaGpuBinary = std::move(CudaGpuBinaryOrErr.get());
890 llvm::Function *ModuleCtorFunc = llvm::Function::Create(
891 llvm::FunctionType::get(VoidTy,
false),
892 llvm::GlobalValue::InternalLinkage,
893 addUnderscoredPrefixToName(
"_module_ctor"), &TheModule);
894 llvm::BasicBlock *CtorEntryBB =
895 llvm::BasicBlock::Create(Context,
"entry", ModuleCtorFunc);
896 CGBuilderTy CtorBuilder(CGM, Context);
898 CtorBuilder.SetInsertPoint(CtorEntryBB);
900 const char *FatbinConstantName;
901 const char *FatbinSectionName;
902 const char *ModuleIDSectionName;
903 StringRef ModuleIDPrefix;
904 llvm::Constant *FatBinStr;
909 CGM.
getTriple().isMacOSX() ?
"__HIP,__hip_fatbin" :
".hip_fatbin";
911 CGM.
getTriple().isMacOSX() ?
"__HIP,__fatbin" :
".hipFatBinSegment";
913 ModuleIDSectionName =
914 CGM.
getTriple().isMacOSX() ?
"__HIP,__module_id" :
"__hip_module_id";
915 ModuleIDPrefix =
"__hip_";
920 const unsigned HIPCodeObjectAlign = 4096;
921 FatBinStr = makeConstantArray(std::string(CudaGpuBinary->getBuffer()),
"",
922 FatbinConstantName, HIPCodeObjectAlign);
928 FatBinStr =
new llvm::GlobalVariable(
930 true, llvm::GlobalValue::ExternalLinkage,
nullptr,
934 nullptr, llvm::GlobalVariable::NotThreadLocal);
938 FatMagic = HIPFatMagic;
940 if (RelocatableDeviceCode)
941 FatbinConstantName = CGM.
getTriple().isMacOSX()
942 ?
"__NV_CUDA,__nv_relfatbin"
946 CGM.
getTriple().isMacOSX() ?
"__NV_CUDA,__nv_fatbin" :
".nv_fatbin";
949 CGM.
getTriple().isMacOSX() ?
"__NV_CUDA,__fatbin" :
".nvFatBinSegment";
951 ModuleIDSectionName = CGM.
getTriple().isMacOSX()
952 ?
"__NV_CUDA,__nv_module_id"
954 ModuleIDPrefix =
"__nv_";
958 FatBinStr = makeConstantArray(std::string(CudaGpuBinary->getBuffer()),
"",
959 FatbinConstantName, 8);
960 FatMagic = CudaFatMagic;
964 ConstantInitBuilder Builder(CGM);
965 auto Values = Builder.beginStruct(FatbinWrapperTy);
967 Values.addInt(IntTy, FatMagic);
969 Values.addInt(IntTy, 1);
971 Values.add(FatBinStr);
973 Values.add(llvm::ConstantPointerNull::get(PtrTy));
974 llvm::GlobalVariable *FatbinWrapper = Values.finishAndCreateGlobal(
977 FatbinWrapper->setSection(FatbinSectionName);
988 auto Linkage = RelocatableDeviceCode ? llvm::GlobalValue::ExternalLinkage
989 : llvm::GlobalValue::InternalLinkage;
990 llvm::BasicBlock *IfBlock =
991 llvm::BasicBlock::Create(Context,
"if", ModuleCtorFunc);
992 llvm::BasicBlock *ExitBlock =
993 llvm::BasicBlock::Create(Context,
"exit", ModuleCtorFunc);
996 GpuBinaryHandle =
new llvm::GlobalVariable(
997 TheModule, PtrTy,
false,
Linkage,
999 !RelocatableDeviceCode ? llvm::ConstantPointerNull::get(PtrTy)
1006 if (
Linkage != llvm::GlobalValue::InternalLinkage)
1007 GpuBinaryHandle->setVisibility(llvm::GlobalValue::HiddenVisibility);
1009 GpuBinaryHandle, PtrTy,
1012 auto *HandleValue = CtorBuilder.CreateLoad(GpuBinaryAddr);
1013 llvm::Constant *
Zero =
1014 llvm::Constant::getNullValue(HandleValue->getType());
1015 llvm::Value *EQZero = CtorBuilder.CreateICmpEQ(HandleValue,
Zero);
1016 CtorBuilder.CreateCondBr(EQZero, IfBlock, ExitBlock);
1019 CtorBuilder.SetInsertPoint(IfBlock);
1021 llvm::CallInst *RegisterFatbinCall =
1022 CtorBuilder.CreateCall(RegisterFatbinFunc, FatbinWrapper);
1023 CtorBuilder.CreateStore(RegisterFatbinCall, GpuBinaryAddr);
1024 CtorBuilder.CreateBr(ExitBlock);
1027 CtorBuilder.SetInsertPoint(ExitBlock);
1029 if (RegisterGlobalsFunc) {
1030 auto *HandleValue = CtorBuilder.CreateLoad(GpuBinaryAddr);
1031 CtorBuilder.CreateCall(RegisterGlobalsFunc, HandleValue);
1034 }
else if (!RelocatableDeviceCode) {
1038 llvm::CallInst *RegisterFatbinCall =
1039 CtorBuilder.CreateCall(RegisterFatbinFunc, FatbinWrapper);
1040 GpuBinaryHandle =
new llvm::GlobalVariable(
1041 TheModule, PtrTy,
false, llvm::GlobalValue::InternalLinkage,
1042 llvm::ConstantPointerNull::get(PtrTy),
"__cuda_gpubin_handle");
1044 CtorBuilder.CreateAlignedStore(RegisterFatbinCall, GpuBinaryHandle,
1048 if (RegisterGlobalsFunc)
1049 CtorBuilder.CreateCall(RegisterGlobalsFunc, RegisterFatbinCall);
1053 CudaFeature::CUDA_USES_FATBIN_REGISTER_END)) {
1056 llvm::FunctionType::get(VoidTy, PtrTy,
false),
1057 "__cudaRegisterFatBinaryEnd");
1058 CtorBuilder.CreateCall(RegisterFatbinEndFunc, RegisterFatbinCall);
1070 SmallString<64> ModuleID;
1071 llvm::raw_svector_ostream
OS(ModuleID);
1072 OS << ModuleIDPrefix
1073 << llvm::format(
"%" PRIx64,
1074 llvm::MD5Hash(TheModule.getSourceFileName()));
1075 llvm::Constant *ModuleIDConstant = makeConstantArray(
1076 std::string(ModuleID),
"", ModuleIDSectionName, 32,
true);
1079 llvm::GlobalAlias::create(llvm::GlobalValue::ExternalLinkage,
1080 Twine(
"__fatbinwrap") + ModuleID, FatbinWrapper);
1084 SmallString<128> RegisterLinkedBinaryName(
"__cudaRegisterLinkedBinary");
1085 RegisterLinkedBinaryName += ModuleID;
1087 getRegisterLinkedBinaryFnTy(), RegisterLinkedBinaryName);
1089 assert(RegisterGlobalsFunc &&
"Expecting at least dummy function!");
1090 llvm::Value *Args[] = {RegisterGlobalsFunc, FatbinWrapper, ModuleIDConstant,
1091 makeDummyFunction(getCallbackFnTy())};
1092 CtorBuilder.CreateCall(RegisterLinkedBinaryFunc, Args);
1098 if (llvm::Function *CleanupFn = makeModuleDtorFunction()) {
1100 llvm::FunctionType *AtExitTy =
1101 llvm::FunctionType::get(IntTy, CleanupFn->getType(),
false);
1102 llvm::FunctionCallee AtExitFunc =
1105 CtorBuilder.CreateCall(AtExitFunc, CleanupFn);
1108 CtorBuilder.CreateRetVoid();
1109 return ModuleCtorFunc;
1131llvm::Function *CGNVCUDARuntime::makeModuleDtorFunction() {
1133 if (!GpuBinaryHandle)
1138 llvm::FunctionType::get(VoidTy, PtrTy,
false),
1139 addUnderscoredPrefixToName(
"UnregisterFatBinary"));
1141 llvm::Function *ModuleDtorFunc = llvm::Function::Create(
1142 llvm::FunctionType::get(VoidTy,
false),
1143 llvm::GlobalValue::InternalLinkage,
1144 addUnderscoredPrefixToName(
"_module_dtor"), &TheModule);
1146 llvm::BasicBlock *DtorEntryBB =
1147 llvm::BasicBlock::Create(Context,
"entry", ModuleDtorFunc);
1148 CGBuilderTy DtorBuilder(CGM, Context);
1149 DtorBuilder.SetInsertPoint(DtorEntryBB);
1152 GpuBinaryHandle, GpuBinaryHandle->getValueType(),
1154 auto *HandleValue = DtorBuilder.CreateLoad(GpuBinaryAddr);
1159 llvm::BasicBlock *IfBlock =
1160 llvm::BasicBlock::Create(Context,
"if", ModuleDtorFunc);
1161 llvm::BasicBlock *ExitBlock =
1162 llvm::BasicBlock::Create(Context,
"exit", ModuleDtorFunc);
1163 llvm::Constant *
Zero = llvm::Constant::getNullValue(HandleValue->getType());
1164 llvm::Value *NEZero = DtorBuilder.CreateICmpNE(HandleValue,
Zero);
1165 DtorBuilder.CreateCondBr(NEZero, IfBlock, ExitBlock);
1167 DtorBuilder.SetInsertPoint(IfBlock);
1168 DtorBuilder.CreateCall(UnregisterFatbinFunc, HandleValue);
1169 DtorBuilder.CreateStore(
Zero, GpuBinaryAddr);
1170 DtorBuilder.CreateBr(ExitBlock);
1172 DtorBuilder.SetInsertPoint(ExitBlock);
1174 DtorBuilder.CreateCall(UnregisterFatbinFunc, HandleValue);
1176 DtorBuilder.CreateRetVoid();
1177 return ModuleDtorFunc;
1181 return new CGNVCUDARuntime(CGM);
1184void CGNVCUDARuntime::internalizeDeviceSideVar(
1201 if (D->
hasAttr<CUDADeviceAttr>() || D->
hasAttr<CUDAConstantAttr>() ||
1202 D->
hasAttr<CUDASharedAttr>() ||
1205 Linkage = llvm::GlobalValue::InternalLinkage;
1209void CGNVCUDARuntime::handleVarRegistration(
const VarDecl *D,
1210 llvm::GlobalVariable &GV) {
1211 if (D->
hasAttr<CUDADeviceAttr>() || D->
hasAttr<CUDAConstantAttr>()) {
1227 D->
hasAttr<HIPManagedAttr>()) {
1229 D->
hasAttr<CUDAConstantAttr>());
1237 const TemplateArgumentList &Args = TD->getTemplateArgs();
1238 if (TD->hasAttr<CUDADeviceBuiltinSurfaceTypeAttr>()) {
1239 assert(Args.
size() == 2 &&
1240 "Unexpected number of template arguments of CUDA device "
1241 "builtin surface type.");
1242 auto SurfType = Args[1].getAsIntegral();
1244 registerDeviceSurf(D, GV, !D->
hasDefinition(), SurfType.getSExtValue());
1246 assert(Args.
size() == 3 &&
1247 "Unexpected number of template arguments of CUDA device "
1248 "builtin texture type.");
1249 auto TexType = Args[1].getAsIntegral();
1250 auto Normalized = Args[2].getAsIntegral();
1252 registerDeviceTex(D, GV, !D->
hasDefinition(), TexType.getSExtValue(),
1253 Normalized.getZExtValue());
1262void CGNVCUDARuntime::transformManagedVars() {
1263 for (
auto &&Info : DeviceVars) {
1264 llvm::GlobalVariable *Var = Info.Var;
1265 if (Info.Flags.getKind() == DeviceVarFlags::Variable &&
1266 Info.Flags.isManaged()) {
1267 auto *ManagedVar =
new llvm::GlobalVariable(
1269 false, Var->getLinkage(),
1270 Var->isDeclaration()
1272 : llvm::ConstantPointerNull::get(Var->getType()),
1274 llvm::GlobalVariable::NotThreadLocal,
1276 ? LangAS::cuda_device
1277 : LangAS::Default));
1278 ManagedVar->setDSOLocal(Var->isDSOLocal());
1279 ManagedVar->setVisibility(Var->getVisibility());
1280 ManagedVar->setExternallyInitialized(
true);
1282 ManagedVar->takeName(Var);
1283 Var->setName(Twine(ManagedVar->getName()) +
".managed");
1286 if (CGM.
getLangOpts().CUDAIsDevice && !Var->isDeclaration()) {
1287 assert(!ManagedVar->isDeclaration());
1298void CGNVCUDARuntime::createOffloadingEntries() {
1300 ? llvm::object::OffloadKind::OFK_HIP
1301 : llvm::object::OffloadKind::OFK_Cuda;
1304 for (KernelInfo &I : EmittedKernels)
1305 llvm::offloading::emitOffloadingEntry(
1306 M, Kind, KernelHandles[I.Kernel->getName()],
1308 llvm::offloading::OffloadGlobalEntry);
1310 for (VarInfo &I : DeviceVars) {
1312 CGM.
getDataLayout().getTypeAllocSize(I.Var->getValueType());
1315 ?
static_cast<int32_t>(llvm::offloading::OffloadGlobalExtern)
1317 (I.Flags.isConstant()
1318 ?
static_cast<int32_t>(llvm::offloading::OffloadGlobalConstant)
1320 (I.Flags.isNormalized()
1321 ?
static_cast<int32_t>(llvm::offloading::OffloadGlobalNormalized)
1323 if (I.Flags.getKind() == DeviceVarFlags::Variable) {
1324 if (I.Flags.isManaged()) {
1325 assert(I.Var->getName().ends_with(
".managed") &&
1326 "HIP managed variables not transformed");
1328 auto *ManagedVar = M.getNamedGlobal(
1329 I.Var->getName().drop_back(StringRef(
".managed").size()));
1330 llvm::offloading::emitOffloadingEntry(
1331 M, Kind, I.Var, getDeviceSideName(I.D), VarSize,
1332 llvm::offloading::OffloadGlobalManagedEntry | Flags,
1333 I.Var->getAlign().valueOrOne().value(), ManagedVar);
1335 llvm::offloading::emitOffloadingEntry(
1336 M, Kind, I.Var, getDeviceSideName(I.D), VarSize,
1337 llvm::offloading::OffloadGlobalEntry | Flags,
1340 }
else if (I.Flags.getKind() == DeviceVarFlags::Surface) {
1341 llvm::offloading::emitOffloadingEntry(
1342 M, Kind, I.Var, getDeviceSideName(I.D), VarSize,
1343 llvm::offloading::OffloadGlobalSurfaceEntry | Flags,
1344 I.Flags.getSurfTexType());
1345 }
else if (I.Flags.getKind() == DeviceVarFlags::Texture) {
1346 llvm::offloading::emitOffloadingEntry(
1347 M, Kind, I.Var, getDeviceSideName(I.D), VarSize,
1348 llvm::offloading::OffloadGlobalTextureEntry | Flags,
1349 I.Flags.getSurfTexType());
1357 if (OffloadProfShadow) {
1358 llvm::offloading::emitOffloadingEntry(
1359 M, Kind, OffloadProfShadow, OffloadProfShadow->getName(),
1361 llvm::offloading::OffloadGlobalEntry, 0);
1363 llvm::LLVMContext &Ctx = M.getContext();
1364 auto *PtrTy = llvm::PointerType::getUnqual(Ctx);
1366 llvm::FunctionType::get(VoidTy, {PtrTy},
false),
1367 "__llvm_profile_offload_register_shadow_variable");
1369 llvm::FunctionType::get(VoidTy, {PtrTy},
false),
1370 "__llvm_profile_offload_register_section_shadow_variable");
1371 auto *CtorFn = llvm::Function::Create(
1372 llvm::FunctionType::get(VoidTy,
false),
1373 llvm::GlobalValue::InternalLinkage,
1375 auto *Entry = llvm::BasicBlock::Create(Ctx,
"entry", CtorFn);
1376 llvm::IRBuilder<> B(Entry);
1377 B.CreateCall(RegisterShadow, {OffloadProfShadow});
1378 if (OffloadProfVersionShadow) {
1380 OffloadProfVersionShadow->getValueType());
1381 auto *VersionEntry = llvm::offloading::emitOffloadingEntry(
1382 M, Kind, OffloadProfVersionShadow,
"__llvm_profile_raw_version",
1383 VersionSize, llvm::offloading::OffloadGlobalEntry, 0);
1386 VersionEntry->setName(VersionEntry->getName() +
"." +
1389 llvm::FunctionType::get(VoidTy, {PtrTy},
false),
1390 "__llvm_profile_offload_register_version_shadow_variable");
1391 B.CreateCall(RegisterVersionShadow, {OffloadProfVersionShadow});
1393 for (
const auto &Info : OffloadProfSectionShadows) {
1394 llvm::offloading::emitOffloadingEntry(
1395 M, Kind, Info.Shadow, Info.DeviceName,
1397 llvm::offloading::OffloadGlobalEntry, 0);
1398 B.CreateCall(RegisterSectionShadow, {Info.Shadow});
1408void CGNVCUDARuntime::emitOffloadProfilingSections() {
1415 if (CUIDHash.empty())
1419 llvm::LLVMContext &Ctx = M.getContext();
1420 std::string Name = (
"__llvm_profile_sections_" + CUIDHash).str();
1424 if (M.getNamedValue(Name))
1431 unsigned GlobalAS = M.getDataLayout().getDefaultGlobalsAddressSpace();
1432 std::string NamesVarPostfixVarName =
1433 std::string(llvm::getInstrProfNamesVarPostfixVarName());
1434 if (!M.getNamedValue(NamesVarPostfixVarName)) {
1435 auto *NamesVarPostfix = llvm::ConstantDataArray::getString(
1436 Ctx, (llvm::Twine(
"_") + CUIDHash).str(),
true);
1437 auto *NamesGV =
new llvm::GlobalVariable(
1438 M, NamesVarPostfix->getType(),
true,
1439 llvm::GlobalValue::PrivateLinkage, NamesVarPostfix,
1440 NamesVarPostfixVarName,
1441 nullptr, llvm::GlobalValue::NotThreadLocal,
1453 auto *PtrTy = llvm::PointerType::getUnqual(Ctx);
1454 OffloadProfShadow =
new llvm::GlobalVariable(
1455 M, PtrTy,
false, llvm::GlobalValue::ExternalLinkage,
1456 llvm::ConstantPointerNull::get(PtrTy), Name);
1462 auto *VersionTy = llvm::Type::getInt64Ty(Ctx);
1463 OffloadProfVersionShadow =
new llvm::GlobalVariable(
1464 M, VersionTy,
false, llvm::GlobalValue::ExternalLinkage,
1465 llvm::ConstantInt::get(VersionTy, 0),
1466 (
"__llvm_profile_shadow_version_" + CUIDHash).str());
1470 auto AddSectionShadow = [&](StringRef
Kind,
const Twine &DeviceName) {
1471 std::string ShadowName =
1472 (Twine(
"__llvm_profile_shadow_") +
Kind +
"_" + CUIDHash +
"_" +
1473 Twine(OffloadProfSectionShadows.size()))
1475 auto *Shadow =
new llvm::GlobalVariable(
1476 M, PtrTy,
false, llvm::GlobalValue::ExternalLinkage,
1477 llvm::ConstantPointerNull::get(PtrTy), ShadowName);
1479 OffloadProfSectionShadows.push_back({Shadow, DeviceName.str()});
1484 for (
auto &&I : EmittedKernels) {
1486 AddSectionShadow(
"data", Twine(
"__profd_") + KernelName);
1487 AddSectionShadow(
"cnts", Twine(
"__profc_") + KernelName);
1488 AddSectionShadow(
"ucnts", Twine(
"__llvm_prf_unifcnt_") + KernelName);
1489 AddSectionShadow(
"names",
1490 Twine(llvm::getInstrProfNamesVarName()) +
"_" + CUIDHash);
1495llvm::Function *CGNVCUDARuntime::finalizeModule() {
1496 transformManagedVars();
1497 emitOffloadProfilingSections();
1509 for (
auto &&Info : DeviceVars) {
1510 auto Kind = Info.Flags.getKind();
1511 if (!Info.Var->isDeclaration() &&
1512 !llvm::GlobalValue::isLocalLinkage(Info.Var->getLinkage()) &&
1513 (Kind == DeviceVarFlags::Variable ||
1514 Kind == DeviceVarFlags::Surface ||
1515 Kind == DeviceVarFlags::Texture) &&
1516 Info.D->isUsed() && !Info.D->hasAttr<UsedAttr>()) {
1523 (CGM.
getLangOpts().OffloadViaLLVM || RelocatableDeviceCode))
1524 createOffloadingEntries();
1526 return makeModuleCtorFunction();
1531llvm::GlobalValue *CGNVCUDARuntime::getKernelHandle(llvm::Function *F,
1533 auto Loc = KernelHandles.find(F->getName());
1534 if (Loc != KernelHandles.end()) {
1535 auto OldHandle = Loc->second;
1536 if (KernelStubs[OldHandle] == F)
1544 KernelStubs[OldHandle] = F;
1549 KernelStubs.erase(OldHandle);
1553 KernelHandles[F->getName()] = F;
1558 auto *Var =
new llvm::GlobalVariable(
1559 TheModule, F->getType(),
true, F->getLinkage(),
1564 Var->setVisibility(F->getVisibility());
1567 auto *FT = FD->getPrimaryTemplate();
1568 if (!FT || FT->isThisDeclarationADefinition())
1570 KernelHandles[F->getName()] = Var;
1571 KernelStubs[Var] = F;
static std::unique_ptr< MangleContext > InitDeviceMC(CodeGenModule &CGM)
static void replaceManagedVar(llvm::GlobalVariable *Var, llvm::GlobalVariable *ManagedVar)
Result
Implement __builtin_bit_cast and related operations.
MangleContext * createMangleContext(const TargetInfo *T=nullptr)
If T is null pointer, assume the target in ASTContext.
bool shouldExternalize(const Decl *D) const
Whether a C++ static variable or CUDA/HIP kernel should be externalized.
StringRef getCUIDHash() const
llvm::SetVector< const VarDecl * > CUDADeviceVarODRUsedByHost
Keep track of CUDA/HIP device-side variables ODR-used by host code.
const TargetInfo * getAuxTargetInfo() const
MangleContext * createDeviceMangleContext(const TargetInfo &T)
Creates a device mangle context to correctly mangle lambdas in a mixed architecture compile by settin...
TypeInfoChars getTypeInfoInChars(const Type *T) const
const TargetInfo & getTargetInfo() const
unsigned getTargetAddressSpace(LangAS AS) const
CharUnits alignTo(CharUnits Align) const
Returns the next integer (mod 2**64) that is greater than or equal to this quantity and is a multiple...
llvm::Align getAsAlign() const
Returns Quantity as a valid llvm::Align, Beware llvm::Align assumes power of two 8-bit bytes.
QuantityType getQuantity() const
Get the raw integer representation of this quantity.
static CharUnits One()
Construct a CharUnits quantity of one.
static CharUnits fromQuantity(QuantityType Quantity)
Construct a CharUnits quantity from a raw integer type.
static CharUnits Zero()
Construct a CharUnits quantity of zero.
bool hasProfileInstr() const
Check if any form of instrumentation is on.
std::string OffloadBinaryToEmbedFile
Name of file passed with -foffload-include-binary option to forward to offloading runtime back-end fo...
llvm::Value * emitRawPointer(CodeGenFunction &CGF) const
Return the pointer contained in this class after authenticating it and adding offset to it if necessa...
llvm::PointerType * getType() const
Return the type of the pointer value.
llvm::StoreInst * CreateStore(llvm::Value *Val, Address Addr, bool IsVolatile=false)
llvm::StoreInst * CreateAlignedStore(llvm::Value *Val, llvm::Value *Addr, CharUnits Align, bool IsVolatile=false)
llvm::StoreInst * CreateDefaultAlignedStore(llvm::Value *Val, llvm::Value *Addr, bool IsVolatile=false)
Address CreateStructGEP(Address Addr, unsigned Index, const llvm::Twine &Name="")
llvm::LoadInst * CreateLoad(Address Addr, const llvm::Twine &Name="")
MangleContext & getMangleContext()
Gets the mangle context.
static CGCallee forDirect(llvm::Constant *functionPtr, const CGCalleeInfo &abstractInfo=CGCalleeInfo())
void add(RValue rvalue, QualType type)
llvm::CallBase * EmitRuntimeCallOrInvoke(llvm::FunctionCallee callee, ArrayRef< llvm::Value * > args, const Twine &name="")
Emits a call or invoke instruction to the given runtime function.
llvm::BasicBlock * createBasicBlock(const Twine &name="", llvm::Function *parent=nullptr, llvm::BasicBlock *before=nullptr)
createBasicBlock - Create an LLVM basic block.
const LangOptions & getLangOpts() const
llvm::AllocaInst * CreateTempAlloca(llvm::Type *Ty, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)
CreateTempAlloca - This creates an alloca and inserts it into the entry block if ArraySize is nullptr...
RValue EmitCall(const CGFunctionInfo &CallInfo, const CGCallee &Callee, ReturnValueSlot ReturnValue, const CallArgList &Args, llvm::CallBase **CallOrInvoke, bool IsMustTail, SourceLocation Loc, bool IsVirtualFunctionPointerThunk=false)
EmitCall - Generate a call of the given function, expecting the given result type,...
RawAddress CreateMemTempWithoutCast(QualType T, const Twine &Name="tmp")
CreateMemTemp - Create a temporary memory object of the given type, with appropriate alignmen without...
RawAddress CreateTempAllocaWithoutCast(llvm::Type *Ty, CharUnits align, const Twine &Name="tmp", llvm::Value *ArraySize=nullptr)
CreateTempAlloca - This creates a alloca and inserts it into the entry block.
const Decl * CurFuncDecl
CurFuncDecl - Holds the Decl for the current outermost non-closure context.
void EmitBranch(llvm::BasicBlock *Block)
EmitBranch - Emit a branch to the specified basic block from the current insert block,...
Address GetAddrOfLocalVar(const VarDecl *VD)
GetAddrOfLocalVar - Return the address of a local variable.
void EmitBlock(llvm::BasicBlock *BB, bool IsFinished=false)
EmitBlock - Emit the given block.
This class organizes the cross-function state that is used while generating LLVM code.
void setDSOLocal(llvm::GlobalValue *GV) const
llvm::Module & getModule() const
llvm::FunctionCallee CreateRuntimeFunction(llvm::FunctionType *Ty, StringRef Name, llvm::AttributeList ExtraAttrs=llvm::AttributeList(), bool Local=false, bool AssumeConvergent=false)
Create or return a runtime function declaration with the specified type and name.
void addCompilerUsedGlobal(llvm::GlobalValue *GV)
Add a global to a list to be added to the llvm.compiler.used metadata.
const IntrusiveRefCntPtr< llvm::vfs::FileSystem > & getFileSystem() const
DiagnosticsEngine & getDiags() const
const LangOptions & getLangOpts() const
CodeGenTypes & getTypes()
const TargetInfo & getTarget() const
const llvm::DataLayout & getDataLayout() const
void Error(SourceLocation loc, StringRef error)
Emit a general error that something can't be done.
CGCXXABI & getCXXABI() const
SanitizerMetadata * getSanitizerMetadata()
const llvm::Triple & getTriple() const
ASTContext & getContext() const
const CodeGenOptions & getCodeGenOpts() const
StringRef getMangledName(GlobalDecl GD)
void maybeSetTrivialComdat(const Decl &D, llvm::GlobalObject &GO)
void AddGlobalCtor(llvm::Function *Ctor, int Priority=65535, unsigned LexOrder=~0U, llvm::Constant *AssociatedData=nullptr)
AddGlobalCtor - Add a function to the list that will be called before main() runs.
void printPostfixForExternalizedDecl(llvm::raw_ostream &OS, const Decl *D) const
Print the postfix for externalized static variable or kernels for single source offloading languages ...
llvm::Type * ConvertType(QualType T)
ConvertType - Convert type T into a llvm::Type.
const CGFunctionInfo & arrangeFunctionDeclaration(const GlobalDecl GD)
Free functions are functions that are compatible with an ordinary C function pointer type.
static RValue get(llvm::Value *V)
static RValue getAggregate(Address addr, bool isVolatile=false)
Convert an Address to an RValue.
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
SourceLocation getLocation() const
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
const ParmVarDecl * getParamDecl(unsigned i) const
GlobalDecl getWithKernelReferenceKind(KernelReferenceKind Kind)
const Decl * getDecl() const
StringRef getName() const
Return the actual identifier string.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
std::string CUID
The user provided compilation unit ID, if non-empty.
GPUDefaultStreamKind GPUDefaultStream
The default stream kind used for HIP kernel launching.
bool shouldMangleDeclName(const NamedDecl *D)
void mangleName(GlobalDecl GD, raw_ostream &)
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
QualType getCanonicalType() const
bool isMicrosoft() const
Is this ABI an MSVC-compatible ABI?
bool isItaniumFamily() const
Does this ABI generally fall into the Itanium family of ABIs?
TargetCXXABI getCXXABI() const
Get the C++ ABI currently in use.
const llvm::VersionTuple & getSDKVersion() const
unsigned size() const
Retrieve the number of template arguments in this template argument list.
static DeclContext * castToDeclContext(const TranslationUnitDecl *D)
CXXRecordDecl * castAsCXXRecordDecl() const
bool isCUDADeviceBuiltinSurfaceType() const
Check if the type is the CUDA device builtin surface type.
bool isCUDADeviceBuiltinTextureType() const
Check if the type is the CUDA device builtin texture type.
Represents a variable declaration or definition.
bool isInline() const
Whether this variable is (C++1z) inline.
bool hasExternalStorage() const
Returns true if a variable has extern or private_extern storage.
DefinitionKind hasDefinition(ASTContext &) const
Check whether this variable is defined in this translation unit.
@ Decl
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
CGCUDARuntime * CreateNVCUDARuntime(CodeGenModule &CGM)
Creates an instance of a CUDA runtime class.
@ VFS
Remove unused -ivfsoverlay arguments.
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
@ Address
A pointer to a ValueDecl.
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
CudaVersion ToCudaVersion(llvm::VersionTuple)
bool CudaFeatureEnabled(llvm::VersionTuple, CudaFeature)
Linkage
Describes the different kinds of linkage (C++ [basic.link], C99 6.2.2) that an entity may have.
U cast(CodeGen::Address addr)
__builtin_bitreverse32 uint32_t __builtin_riscv_aaddu_u32 __builtin_riscv_asubu_u32 int32_t
llvm::IntegerType * Int8Ty
i8, i16, i32, and i64
llvm::IntegerType * SizeTy
llvm::IntegerType * IntTy
int
CharUnits getSizeAlign() const
CharUnits getPointerAlign() const
llvm::PointerType * DefaultPtrTy