37constexpr unsigned CudaFatMagic = 0x466243b1;
38constexpr unsigned HIPFatMagic = 0x48495046;
41 return M.getDataLayout().getIntPtrType(M.getContext());
47 return T.isOSBinFormatMachO() ?
"__TEXT,__StaticInit" :
".text.startup";
133 auto [EntriesB, EntriesE] = EntryArray;
139 ImagesInits.
reserve(Bufs.size());
145 ".omp_offloading.device_image" + Suffix);
147 Image->setSection(Relocatable ?
".llvm.offloading.relocatable"
148 :
".llvm.offloading");
166 Binary.bytes_begin() + Header->EntriesOffset);
167 BeginOffset = Entry->ImageOffset;
168 EndOffset = Entry->ImageOffset + Entry->ImageSize;
171 auto *Begin = ConstantInt::get(
getSizeTTy(M), BeginOffset);
182 ImageE, EntriesB, EntriesE));
192 ".omp_offloading.device_images" + Suffix);
203 ".omp_offloading.descriptor" + Suffix);
212 ".omp_offloading.descriptor_unreg" + Suffix, &M);
213 Func->setSection(getStartupSection(M.getTargetTriple()));
219 M.getOrInsertFunction(
"__tgt_unregister_lib", UnRegFuncTy);
223 Builder.CreateCall(UnRegFuncC, BinDesc);
224 Builder.CreateRetVoid();
234 ".omp_offloading.descriptor_reg" + Suffix, &M);
235 Func->setSection(getStartupSection(M.getTargetTriple()));
241 M.getOrInsertFunction(
"__tgt_register_lib", RegFuncTy);
245 FunctionCallee AtExit = M.getOrInsertFunction(
"atexit", AtExitTy);
247 Function *UnregFunc = createUnregisterFunction(M, BinDesc, Suffix);
252 Builder.CreateCall(RegFuncC, BinDesc);
258 Builder.CreateCall(AtExit, UnregFunc);
259 Builder.CreateRetVoid();
291 IsHIP ? (
Triple.
isMacOSX() ?
"__HIP,__hip_fatbin" :
".hip_fatbin")
292 : (
Triple.isMacOSX() ?
"__NV_CUDA,__nv_fatbin" :
".nv_fatbin");
296 ".fatbin_image" + Suffix);
297 Fatbin->setSection(FatbinConstantSection);
301 IsHIP ? (
Triple.
isMacOSX() ?
"__HIP,__fatbin" :
".hipFatBinSegment")
302 : (
Triple.isMacOSX() ?
"__NV_CUDA,__fatbin" :
".nvFatBinSegment");
315 FatbinInitializer,
".fatbin_wrapper" + Suffix);
316 FatbinDesc->setSection(FatbinWrapperSection);
317 FatbinDesc->setAlignment(
Align(8));
318 FatbinDesc->setNoSanitizeMetadata();
352 bool EmitSurfacesAndTextures) {
354 auto [EntriesB, EntriesE] = EntryArray;
363 Int8PtrTy, Int8PtrTy, Int8PtrTy, Int8PtrTy, Int32PtrTy},
366 IsHIP ?
"__hipRegisterFunction" :
"__cudaRegisterFunction", RegFuncTy);
375 IsHIP ?
"__hipRegisterVar" :
"__cudaRegisterVar", RegVarTy);
380 {Int8PtrPtrTy, Int8PtrTy, Int8PtrTy, Int8PtrTy,
384 IsHIP ?
"__hipRegisterManagedVar" :
"__cudaRegisterManagedVar",
390 {Int8PtrPtrTy, Int8PtrTy, Int8PtrTy, Int8PtrTy,
394 IsHIP ?
"__hipRegisterSurface" :
"__cudaRegisterSurface", RegSurfaceTy);
403 IsHIP ?
"__hipRegisterTexture" :
"__cudaRegisterTexture", RegTextureTy);
409 IsHIP ?
".hip.globals_reg" :
".cuda.globals_reg", &M);
410 RegGlobalsFn->setSection(getStartupSection(M.getTargetTriple()));
425 auto *EntryCmp = Builder.CreateICmpNE(EntriesB, EntriesE);
426 Builder.CreateCondBr(EntryCmp, EntryBB, ExitBB);
427 Builder.SetInsertPoint(EntryBB);
433 auto *Addr = Builder.CreateLoad(Int8PtrTy, AddrPtr,
"addr");
438 auto *AuxAddr = Builder.CreateLoad(Int8PtrTy, AuxAddrPtr,
"aux_addr");
448 auto *
Name = Builder.CreateLoad(Int8PtrTy, NamePtr,
"name");
463 auto *
Data = Builder.CreateTrunc(
466 auto *
Type = Builder.CreateAnd(
470 auto *ExternBit = Builder.CreateAnd(
473 auto *
Extern = Builder.CreateLShr(
478 auto *
Const = Builder.CreateLShr(
480 auto *NormalizedBit = Builder.CreateAnd(
483 auto *Normalized = Builder.CreateLShr(
485 auto *KindCond = Builder.CreateICmpEQ(
489 Builder.CreateCondBr(KindCond, IfKindBB, IfEndBB);
490 Builder.SetInsertPoint(IfKindBB);
491 auto *FnCond = Builder.CreateICmpEQ(
493 Builder.CreateCondBr(FnCond, IfThenBB, IfElseBB);
496 Builder.SetInsertPoint(IfThenBB);
499 {RegGlobalsFn->arg_begin(), Addr,
Name,
Name,
504 Builder.CreateBr(IfEndBB);
505 Builder.SetInsertPoint(IfElseBB);
507 auto *
Switch = Builder.CreateSwitch(
Type, IfEndBB);
509 Builder.SetInsertPoint(SwGlobalBB);
510 Builder.CreateCall(RegVar,
513 Builder.CreateBr(IfEndBB);
518 Builder.SetInsertPoint(SwManagedBB);
519 Builder.CreateCall(RegManagedVar, {RegGlobalsFn->arg_begin(), AuxAddr, Addr,
521 Builder.CreateBr(IfEndBB);
525 Builder.SetInsertPoint(SwSurfaceBB);
526 if (EmitSurfacesAndTextures)
527 Builder.CreateCall(RegSurface, {RegGlobalsFn->arg_begin(), Addr,
Name,
Name,
529 Builder.CreateBr(IfEndBB);
534 Builder.SetInsertPoint(SwTextureBB);
535 if (EmitSurfacesAndTextures)
536 Builder.CreateCall(RegTexture, {RegGlobalsFn->arg_begin(), Addr,
Name,
Name,
538 Builder.CreateBr(IfEndBB);
542 Builder.SetInsertPoint(IfEndBB);
543 auto *NewEntry = Builder.CreateInBoundsGEP(
545 auto *
Cmp = Builder.CreateICmpEQ(NewEntry, EntriesE);
546 Entry->addIncoming(EntriesB, &RegGlobalsFn->getEntryBlock());
547 Entry->addIncoming(NewEntry, IfEndBB);
548 Builder.CreateCondBr(Cmp, ExitBB, EntryBB);
549 Builder.SetInsertPoint(ExitBB);
550 Builder.CreateRetVoid();
560 bool EmitSurfacesAndTextures) {
565 (IsHIP ?
".hip.fatbin_reg" :
".cuda.fatbin_reg") + Suffix, &M);
566 CtorFunc->setSection(getStartupSection(M.getTargetTriple()));
571 (IsHIP ?
".hip.fatbin_unreg" :
".cuda.fatbin_unreg") + Suffix, &M);
572 DtorFunc->setSection(getStartupSection(M.getTargetTriple()));
579 IsHIP ?
"__hipRegisterFatBinary" :
"__cudaRegisterFatBinary", RegFatTy);
584 M.getOrInsertFunction(
"__cudaRegisterFatBinaryEnd", RegFatEndTy);
589 IsHIP ?
"__hipUnregisterFatBinary" :
"__cudaUnregisterFatBinary",
594 FunctionCallee AtExit = M.getOrInsertFunction(
"atexit", AtExitTy);
599 (IsHIP ?
".hip.binary_handle" :
".cuda.binary_handle") + Suffix);
603 CallInst *Handle = CtorBuilder.CreateCall(
606 CtorBuilder.CreateAlignedStore(
607 Handle, BinaryHandleGlobal,
608 Align(M.getDataLayout().getPointerTypeSize(PtrTy)));
609 CtorBuilder.CreateCall(createRegisterGlobalsFunction(M, IsHIP, EntryArray,
611 EmitSurfacesAndTextures),
614 CtorBuilder.CreateCall(RegFatbinEnd, Handle);
615 CtorBuilder.CreateCall(AtExit, DtorFunc);
616 CtorBuilder.CreateRetVoid();
622 LoadInst *BinaryHandle = DtorBuilder.CreateAlignedLoad(
623 PtrTy, BinaryHandleGlobal,
624 Align(M.getDataLayout().getPointerTypeSize(PtrTy)));
625 DtorBuilder.CreateCall(UnregFatbin, BinaryHandle);
626 DtorBuilder.CreateRetVoid();
635 SYCLWrapper(
Module &M,
const SYCLJITOptions &Options,
bool IsFinalizedImage)
637 IsFinalizedImage(IsFinalizedImage) {}
642 std::pair<Constant *, Constant *> embedBinary(ArrayRef<char> Buffer) {
644 GlobalVariable *BinaryGV =
new GlobalVariable(
646 Arr,
".sycl_offloading.binary");
650 BinaryGV->
setSection(IsFinalizedImage ?
".sycl_fatbin"
651 :
".llvm.offloading");
653 IntegerType *Int64Ty = Type::getInt64Ty(C);
661 Function *createRegisterFatbinFunction(Constant *Start, Constant *
Size) {
662 FunctionType *FuncTy =
663 FunctionType::get(Type::getVoidTy(C),
false);
665 Twine(
"sycl") +
".descriptor_reg", &M);
666 Func->setSection(getStartupSection(M.getTargetTriple()));
669 IntegerType *Int64Ty = Type::getInt64Ty(C);
670 FunctionType *RegFuncTy =
671 FunctionType::get(Type::getVoidTy(C), {PtrTy, Int64Ty},
673 FunctionCallee RegFuncC =
674 M.getOrInsertFunction(
"__sycl_register_lib", RegFuncTy);
676 FunctionType *AtExitTy =
677 FunctionType::get(Type::getInt32Ty(C), PtrTy,
false);
678 FunctionCallee AtExit = M.getOrInsertFunction(
"atexit", AtExitTy);
680 Function *UnregFunc = createUnregisterFunction(Start,
Size);
683 Builder.CreateCall(RegFuncC, {
Start,
Size});
688 Builder.CreateCall(AtExit, UnregFunc);
689 Builder.CreateRetVoid();
695 Function *createUnregisterFunction(Constant *Start, Constant *
Size) {
696 FunctionType *FuncTy =
697 FunctionType::get(Type::getVoidTy(C),
false);
699 "sycl.descriptor_unreg", &M);
700 Func->setSection(getStartupSection(M.getTargetTriple()));
703 IntegerType *Int64Ty = Type::getInt64Ty(C);
704 FunctionType *UnRegFuncTy =
705 FunctionType::get(Type::getVoidTy(C), {PtrTy, Int64Ty},
707 FunctionCallee UnRegFuncC =
708 M.getOrInsertFunction(
"__sycl_unregister_lib", UnRegFuncTy);
711 Builder.CreateCall(UnRegFuncC, {
Start,
Size});
712 Builder.CreateRetVoid();
719 SYCLJITOptions Options;
720 bool IsFinalizedImage;
729 createBinDesc(M, Images, EntryArray, Suffix, Relocatable);
732 "No binary descriptors created.");
733 createRegisterFunction(M,
Desc, Suffix);
740 bool EmitSurfacesAndTextures) {
744 "No fatbin section created.");
746 createRegisterFatbinFunction(M,
Desc,
false, EntryArray, Suffix,
747 EmitSurfacesAndTextures);
753 bool EmitSurfacesAndTextures) {
757 "No fatbin section created.");
759 createRegisterFatbinFunction(M,
Desc,
true, EntryArray, Suffix,
760 EmitSurfacesAndTextures);
766 bool IsFinalizedImage,
768 SYCLWrapper W(M,
Options, IsFinalizedImage);
769 auto [Start,
Size] = W.embedBinary(Buffer);
770 Function *RegisterFunc = W.createRegisterFatbinFunction(Start,
Size);
771 if (RegistrationFunc) {
772 *RegistrationFunc = RegisterFunc;
static IntegerType * getSizeTTy(IRBuilderBase &B, const TargetLibraryInfo *TLI)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
Module.h This file contains the declarations for the Module class.
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
This file defines the SmallVector class.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
Get the array size.
static LLVM_ABI ArrayType * get(Type *ElementType, uint64_t NumElements)
This static method is the primary way to construct an ArrayType.
static BasicBlock * Create(LLVMContext &Context, const Twine &Name="", Function *Parent=nullptr, BasicBlock *InsertBefore=nullptr)
Creates a new BasicBlock.
This class represents a function call, abstracting a target machine's calling convention.
static LLVM_ABI Constant * get(ArrayType *T, ArrayRef< Constant * > V)
static Constant * get(LLVMContext &Context, ArrayRef< ElementTy > Elts)
get() constructor - Return a constant with array type with an element count and element type matching...
static LLVM_ABI Constant * getPointerBitCastOrAddrSpaceCast(Constant *C, Type *Ty)
Create a BitCast or AddrSpaceCast for a pointer type depending on the address space.
static Constant * getGetElementPtr(Type *Ty, Constant *C, ArrayRef< Constant * > IdxList, GEPNoWrapFlags NW=GEPNoWrapFlags::none(), std::optional< ConstantRange > InRange=std::nullopt, Type *OnlyIfReducedTy=nullptr)
Getelementptr form.
static LLVM_ABI ConstantPointerNull * get(PointerType *T)
Static factory methods - Return objects of the specified value.
static LLVM_ABI Constant * get(StructType *T, ArrayRef< Constant * > V)
This is an important base class in LLVM.
static LLVM_ABI Constant * getAllOnesValue(Type *Ty)
static LLVM_ABI Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
Lightweight error class with error context and mandatory checking.
static ErrorSuccess success()
Create a success value.
A handy container for a FunctionType+Callee-pointer pair, which can be passed around as a single enti...
static LLVM_ABI FunctionType * get(Type *Result, ArrayRef< Type * > Params, bool isVarArg)
This static method is the primary way of constructing a FunctionType.
static Function * Create(FunctionType *Ty, LinkageTypes Linkage, unsigned AddrSpace, const Twine &N="", Module *M=nullptr)
LLVM_ABI void setSection(StringRef S)
Change the section for this global.
void setUnnamedAddr(UnnamedAddr Val)
@ InternalLinkage
Rename collisions when linking (static functions).
Type * getValueType() const
This provides a uniform API for creating instructions and inserting them into a basic block: either a...
Class to represent integer types.
This is an important class for using LLVM in a threaded context.
An instruction for reading from memory.
A Module instance is used to store all the information related to an LLVM module.
static PointerType * getUnqual(LLVMContext &C)
This constructs an opaque pointer to an object in the default address space (address space zero).
static LLVM_ABI PointerType * get(LLVMContext &C, unsigned AddressSpace)
This constructs an opaque pointer to an object in a numbered address space.
void reserve(size_type N)
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Class to represent struct types.
static LLVM_ABI StructType * getTypeByName(LLVMContext &C, StringRef Name)
Return the type with the specified name, or null if there is none by that name.
static LLVM_ABI StructType * create(LLVMContext &Context, StringRef Name)
This creates an identified struct.
Triple - Helper class for working with autoconf configuration names.
bool isMacOSX() const
Is this a Mac OS X triple.
The instances of the Type class are immutable: once they are created, they are never changed.
static LLVM_ABI IntegerType * getInt64Ty(LLVMContext &C)
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
static LLVM_ABI Type * getVoidTy(LLVMContext &C)
static LLVM_ABI IntegerType * getInt16Ty(LLVMContext &C)
Type * getType() const
All values are typed, get the type of this value.
static uint64_t getAlignment()
@ Switch
The "resume-switch" lowering, where there are separate resume and destroy functions that are shared b...
LLVM_ABI StructType * getEntryTy(Module &M)
Returns the type of the offloading entry we use to store kernels and globals that will be registered ...
@ OffloadGlobalSurfaceEntry
Mark the entry as a surface variable.
@ OffloadGlobalTextureEntry
Mark the entry as a texture variable.
@ OffloadGlobalNormalized
Mark the entry as being a normalized surface.
@ OffloadGlobalEntry
Mark the entry as a global entry.
@ OffloadGlobalManagedEntry
Mark the entry as a managed global variable.
@ OffloadGlobalExtern
Mark the entry as being extern.
@ OffloadGlobalConstant
Mark the entry as being constant.
LLVM_ABI llvm::Error wrapSYCLBinaries(llvm::Module &M, llvm::ArrayRef< char > Buffer, SYCLJITOptions Options=SYCLJITOptions(), bool IsFinalizedImage=false, llvm::Function **RegistrationFunc=nullptr)
Wraps OffloadBinaries in the given Buffers into the module M as global symbols and registers the imag...
LLVM_ABI llvm::Error wrapOpenMPBinaries(llvm::Module &M, llvm::ArrayRef< llvm::ArrayRef< char > > Images, EntryArrayTy EntryArray, llvm::StringRef Suffix="", bool Relocatable=false)
Wraps the input device images into the module M as global symbols and registers the images with the O...
std::pair< Constant *, Constant * > EntryArrayTy
LLVM_ABI llvm::Error wrapHIPBinary(llvm::Module &M, llvm::ArrayRef< char > Images, EntryArrayTy EntryArray, llvm::StringRef Suffix="", bool EmitSurfacesAndTextures=true)
Wraps the input bundled image into the module M as global symbols and registers the images with the H...
LLVM_ABI llvm::Error wrapCudaBinary(llvm::Module &M, llvm::ArrayRef< char > Images, EntryArrayTy EntryArray, llvm::StringRef Suffix="", bool EmitSurfacesAndTextures=true)
Wraps the input fatbinary image into the module M as global symbols and registers the images with the...
NodeAddr< FuncNode * > Func
This is an optimization pass for GlobalISel generic memory operations.
LLVM_ABI file_magic identify_magic(StringRef magic)
Identify the type of a binary file based on how magical it is.
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
IRBuilder(LLVMContext &, FolderTy, InserterTy, MDNode *, ArrayRef< OperandBundleDef >) -> IRBuilder< FolderTy, InserterTy >
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI void appendToGlobalCtors(Module &M, Function *F, int Priority, Constant *Data=nullptr)
Append F to the list of global ctors of module M with the given Priority.
@ Extern
Replace returns with jump to thunk, don't emit thunk.
This struct is a compact representation of a valid (non-zero power of two) alignment.
@ offload_binary
LLVM offload object file.