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;
137 ImagesInits.
reserve(Bufs.size());
143 ".llvm_offloading.device_image" + Suffix);
145 Image->setSection(Relocatable ?
".llvm.offloading.relocatable"
146 :
".llvm.offloading");
164 Binary.bytes_begin() + Header->EntriesOffset);
165 BeginOffset = Entry->ImageOffset;
166 EndOffset = Entry->ImageOffset + Entry->ImageSize;
169 auto *Begin = ConstantInt::get(
getSizeTTy(M), BeginOffset);
175 ImageE, EntriesB, EntriesE));
185 ".llvm_offloading.device_images" + Suffix);
196 ".llvm_offloading.descriptor" + Suffix);
205 ".llvm_offloading.descriptor_unreg" + Suffix, &M);
206 Func->setSection(getStartupSection(M.getTargetTriple()));
211 FunctionCallee UnRegFuncC = M.getOrInsertFunction(UnregFuncName, UnRegFuncTy);
215 Builder.CreateCall(UnRegFuncC, BinDesc);
216 Builder.CreateRetVoid();
227 ".llvm_offloading.descriptor_reg" + Suffix, &M);
228 Func->setSection(getStartupSection(M.getTargetTriple()));
233 FunctionCallee RegFuncC = M.getOrInsertFunction(RegFuncName, RegFuncTy);
237 FunctionCallee AtExit = M.getOrInsertFunction(
"atexit", AtExitTy);
240 createUnregisterFunction(M, BinDesc, Suffix, UnregFuncName);
245 Builder.CreateCall(RegFuncC, BinDesc);
251 Builder.CreateCall(AtExit, UnregFunc);
252 Builder.CreateRetVoid();
284 IsHIP ? (
Triple.
isMacOSX() ?
"__HIP,__hip_fatbin" :
".hip_fatbin")
285 : (
Triple.isMacOSX() ?
"__NV_CUDA,__nv_fatbin" :
".nv_fatbin");
289 ".fatbin_image" + Suffix);
290 Fatbin->setSection(FatbinConstantSection);
294 IsHIP ? (
Triple.
isMacOSX() ?
"__HIP,__fatbin" :
".hipFatBinSegment")
295 : (
Triple.isMacOSX() ?
"__NV_CUDA,__fatbin" :
".nvFatBinSegment");
308 FatbinInitializer,
".fatbin_wrapper" + Suffix);
309 FatbinDesc->setSection(FatbinWrapperSection);
310 FatbinDesc->setAlignment(
Align(8));
311 FatbinDesc->setNoSanitizeMetadata();
345 bool EmitSurfacesAndTextures) {
347 auto [EntriesB, EntriesE] = EntryArray;
356 Int8PtrTy, Int8PtrTy, Int8PtrTy, Int8PtrTy, Int32PtrTy},
359 IsHIP ?
"__hipRegisterFunction" :
"__cudaRegisterFunction", RegFuncTy);
368 IsHIP ?
"__hipRegisterVar" :
"__cudaRegisterVar", RegVarTy);
373 {Int8PtrPtrTy, Int8PtrTy, Int8PtrTy, Int8PtrTy,
377 IsHIP ?
"__hipRegisterManagedVar" :
"__cudaRegisterManagedVar",
383 {Int8PtrPtrTy, Int8PtrTy, Int8PtrTy, Int8PtrTy,
387 IsHIP ?
"__hipRegisterSurface" :
"__cudaRegisterSurface", RegSurfaceTy);
396 IsHIP ?
"__hipRegisterTexture" :
"__cudaRegisterTexture", RegTextureTy);
402 IsHIP ?
".hip.globals_reg" :
".cuda.globals_reg", &M);
403 RegGlobalsFn->setSection(getStartupSection(M.getTargetTriple()));
407 Builder.disableGEPCanonicalization();
419 auto *EntryCmp = Builder.CreateICmpNE(EntriesB, EntriesE);
420 Builder.CreateCondBr(EntryCmp, EntryBB, ExitBB);
421 Builder.SetInsertPoint(EntryBB);
427 auto *Addr = Builder.CreateLoad(Int8PtrTy, AddrPtr,
"addr");
432 auto *AuxAddr = Builder.CreateLoad(Int8PtrTy, AuxAddrPtr,
"aux_addr");
442 auto *
Name = Builder.CreateLoad(Int8PtrTy, NamePtr,
"name");
457 auto *
Data = Builder.CreateTrunc(
460 auto *
Type = Builder.CreateAnd(
464 auto *ExternBit = Builder.CreateAnd(
467 auto *
Extern = Builder.CreateLShr(
472 auto *
Const = Builder.CreateLShr(
474 auto *NormalizedBit = Builder.CreateAnd(
477 auto *Normalized = Builder.CreateLShr(
479 auto *KindCond = Builder.CreateICmpEQ(
483 Builder.CreateCondBr(KindCond, IfKindBB, IfEndBB);
484 Builder.SetInsertPoint(IfKindBB);
485 auto *FnCond = Builder.CreateICmpEQ(
487 Builder.CreateCondBr(FnCond, IfThenBB, IfElseBB);
490 Builder.SetInsertPoint(IfThenBB);
493 {RegGlobalsFn->arg_begin(), Addr,
Name,
Name,
498 Builder.CreateBr(IfEndBB);
499 Builder.SetInsertPoint(IfElseBB);
501 auto *
Switch = Builder.CreateSwitch(
Type, IfEndBB);
503 Builder.SetInsertPoint(SwGlobalBB);
504 Builder.CreateCall(RegVar,
507 Builder.CreateBr(IfEndBB);
512 Builder.SetInsertPoint(SwManagedBB);
513 Builder.CreateCall(RegManagedVar, {RegGlobalsFn->arg_begin(), AuxAddr, Addr,
515 Builder.CreateBr(IfEndBB);
519 Builder.SetInsertPoint(SwSurfaceBB);
520 if (EmitSurfacesAndTextures)
521 Builder.CreateCall(RegSurface, {RegGlobalsFn->arg_begin(), Addr,
Name,
Name,
523 Builder.CreateBr(IfEndBB);
528 Builder.SetInsertPoint(SwTextureBB);
529 if (EmitSurfacesAndTextures)
530 Builder.CreateCall(RegTexture, {RegGlobalsFn->arg_begin(), Addr,
Name,
Name,
532 Builder.CreateBr(IfEndBB);
536 Builder.SetInsertPoint(IfEndBB);
537 auto *NewEntry = Builder.CreateInBoundsGEP(
539 auto *
Cmp = Builder.CreateICmpEQ(NewEntry, EntriesE);
540 Entry->addIncoming(EntriesB, &RegGlobalsFn->getEntryBlock());
541 Entry->addIncoming(NewEntry, IfEndBB);
542 Builder.CreateCondBr(Cmp, ExitBB, EntryBB);
543 Builder.SetInsertPoint(ExitBB);
544 Builder.CreateRetVoid();
554 bool EmitSurfacesAndTextures) {
559 (IsHIP ?
".hip.fatbin_reg" :
".cuda.fatbin_reg") + Suffix, &M);
560 CtorFunc->setSection(getStartupSection(M.getTargetTriple()));
565 (IsHIP ?
".hip.fatbin_unreg" :
".cuda.fatbin_unreg") + Suffix, &M);
566 DtorFunc->setSection(getStartupSection(M.getTargetTriple()));
573 IsHIP ?
"__hipRegisterFatBinary" :
"__cudaRegisterFatBinary", RegFatTy);
578 M.getOrInsertFunction(
"__cudaRegisterFatBinaryEnd", RegFatEndTy);
583 IsHIP ?
"__hipUnregisterFatBinary" :
"__cudaUnregisterFatBinary",
588 FunctionCallee AtExit = M.getOrInsertFunction(
"atexit", AtExitTy);
593 (IsHIP ?
".hip.binary_handle" :
".cuda.binary_handle") + Suffix);
597 CallInst *Handle = CtorBuilder.CreateCall(
600 CtorBuilder.CreateAlignedStore(
601 Handle, BinaryHandleGlobal,
602 Align(M.getDataLayout().getPointerTypeSize(PtrTy)));
603 CtorBuilder.CreateCall(createRegisterGlobalsFunction(M, IsHIP, EntryArray,
605 EmitSurfacesAndTextures),
608 CtorBuilder.CreateCall(RegFatbinEnd, Handle);
609 CtorBuilder.CreateCall(AtExit, DtorFunc);
610 CtorBuilder.CreateRetVoid();
616 LoadInst *BinaryHandle = DtorBuilder.CreateAlignedLoad(
617 PtrTy, BinaryHandleGlobal,
618 Align(M.getDataLayout().getPointerTypeSize(PtrTy)));
619 DtorBuilder.CreateCall(UnregFatbin, BinaryHandle);
620 DtorBuilder.CreateRetVoid();
629 SYCLWrapper(
Module &M,
const SYCLJITOptions &Options,
bool IsFinalizedImage)
631 IsFinalizedImage(IsFinalizedImage) {}
636 std::pair<Constant *, Constant *> embedBinary(ArrayRef<char> Buffer) {
638 GlobalVariable *BinaryGV =
new GlobalVariable(
640 Arr,
".sycl_offloading.binary");
644 BinaryGV->
setSection(IsFinalizedImage ?
".sycl_fatbin"
645 :
".llvm.offloading");
647 IntegerType *Int64Ty = Type::getInt64Ty(C);
649 return {BinaryGV,
Size};
652 Function *createRegisterFatbinFunction(Constant *Start, Constant *
Size) {
653 FunctionType *FuncTy =
654 FunctionType::get(Type::getVoidTy(C),
false);
656 Twine(
"sycl") +
".descriptor_reg", &M);
657 Func->setSection(getStartupSection(M.getTargetTriple()));
660 IntegerType *Int64Ty = Type::getInt64Ty(C);
661 FunctionType *RegFuncTy =
662 FunctionType::get(Type::getVoidTy(C), {PtrTy, Int64Ty},
664 FunctionCallee RegFuncC =
665 M.getOrInsertFunction(
"__sycl_register_lib", RegFuncTy);
667 FunctionType *AtExitTy =
668 FunctionType::get(Type::getInt32Ty(C), PtrTy,
false);
669 FunctionCallee AtExit = M.getOrInsertFunction(
"atexit", AtExitTy);
671 Function *UnregFunc = createUnregisterFunction(Start,
Size);
674 Builder.CreateCall(RegFuncC, {
Start,
Size});
679 Builder.CreateCall(AtExit, UnregFunc);
680 Builder.CreateRetVoid();
686 Function *createUnregisterFunction(Constant *Start, Constant *
Size) {
687 FunctionType *FuncTy =
688 FunctionType::get(Type::getVoidTy(C),
false);
690 "sycl.descriptor_unreg", &M);
691 Func->setSection(getStartupSection(M.getTargetTriple()));
694 IntegerType *Int64Ty = Type::getInt64Ty(C);
695 FunctionType *UnRegFuncTy =
696 FunctionType::get(Type::getVoidTy(C), {PtrTy, Int64Ty},
698 FunctionCallee UnRegFuncC =
699 M.getOrInsertFunction(
"__sycl_unregister_lib", UnRegFuncTy);
702 Builder.CreateCall(UnRegFuncC, {
Start,
Size});
703 Builder.CreateRetVoid();
710 SYCLJITOptions Options;
711 bool IsFinalizedImage;
725 createBinDesc(M, Images, EntryArray, Suffix, Relocatable);
728 "No binary descriptors created.");
729 createRegisterFunction(M,
Desc, Suffix, RegFuncName, UnregFuncName);
737 "__tgt_register_lib",
"__tgt_unregister_lib");
745 "__tgt_acc_register_lib",
746 "__tgt_acc_unregister_lib");
752 bool EmitSurfacesAndTextures) {
756 "No fatbin section created.");
758 createRegisterFatbinFunction(M,
Desc,
false, EntryArray, Suffix,
759 EmitSurfacesAndTextures);
765 bool EmitSurfacesAndTextures) {
769 "No fatbin section created.");
771 createRegisterFatbinFunction(M,
Desc,
true, EntryArray, Suffix,
772 EmitSurfacesAndTextures);
778 bool IsFinalizedImage,
780 SYCLWrapper W(M,
Options, IsFinalizedImage);
781 auto [Start,
Size] = W.embedBinary(Buffer);
782 Function *RegisterFunc = W.createRegisterFatbinFunction(Start,
Size);
783 if (RegistrationFunc) {
784 *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.
static Error wrapOmpAccBinaries(Module &M, ArrayRef< ArrayRef< char > > Images, offloading::EntryArrayTy EntryArray, StringRef Suffix, bool Relocatable, StringRef RegFuncName, StringRef UnregFuncName)
Wraps the images and registers them with the runtime through the given registration entry points.
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 * getPtrAdd(Constant *Ptr, Constant *Offset, GEPNoWrapFlags NW=GEPNoWrapFlags::none(), std::optional< ConstantRange > InRange=std::nullopt, Type *OnlyIfReduced=nullptr)
Create a getelementptr i8, ptr, offset constant expression.
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).
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...
LLVM_ABI llvm::Error wrapOpenACCBinaries(llvm::Module &M, llvm::ArrayRef< llvm::ArrayRef< char > > Images, EntryArrayTy EntryArray, bool Relocatable=false)
Wraps the input device images into the module M as global symbols and registers the images with the O...
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) -> IRBuilder< FolderTy, InserterTy >
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.