40constexpr unsigned CudaFatMagic = 0x466243b1;
41constexpr unsigned HIPFatMagic = 0x48495046;
44 return M.getDataLayout().getIntPtrType(M.getContext());
50 return T.isOSBinFormatMachO() ?
"__TEXT,__StaticInit" :
".text.startup";
136 auto [EntriesB, EntriesE] = EntryArray;
142 ImagesInits.
reserve(Bufs.size());
148 ".omp_offloading.device_image" + Suffix);
150 Image->setSection(Relocatable ?
".llvm.offloading.relocatable"
151 :
".llvm.offloading");
169 Binary.bytes_begin() + Header->EntriesOffset);
170 BeginOffset = Entry->ImageOffset;
171 EndOffset = Entry->ImageOffset + Entry->ImageSize;
174 auto *Begin = ConstantInt::get(
getSizeTTy(M), BeginOffset);
185 ImageE, EntriesB, EntriesE));
195 ".omp_offloading.device_images" + Suffix);
206 ".omp_offloading.descriptor" + Suffix);
215 ".omp_offloading.descriptor_unreg" + Suffix, &M);
216 Func->setSection(getStartupSection(M.getTargetTriple()));
222 M.getOrInsertFunction(
"__tgt_unregister_lib", UnRegFuncTy);
226 Builder.CreateCall(UnRegFuncC, BinDesc);
227 Builder.CreateRetVoid();
237 ".omp_offloading.descriptor_reg" + Suffix, &M);
238 Func->setSection(getStartupSection(M.getTargetTriple()));
244 M.getOrInsertFunction(
"__tgt_register_lib", RegFuncTy);
248 FunctionCallee AtExit = M.getOrInsertFunction(
"atexit", AtExitTy);
250 Function *UnregFunc = createUnregisterFunction(M, BinDesc, Suffix);
255 Builder.CreateCall(RegFuncC, BinDesc);
261 Builder.CreateCall(AtExit, UnregFunc);
262 Builder.CreateRetVoid();
294 IsHIP ? (
Triple.
isMacOSX() ?
"__HIP,__hip_fatbin" :
".hip_fatbin")
295 : (
Triple.isMacOSX() ?
"__NV_CUDA,__nv_fatbin" :
".nv_fatbin");
299 ".fatbin_image" + Suffix);
300 Fatbin->setSection(FatbinConstantSection);
304 IsHIP ? (
Triple.
isMacOSX() ?
"__HIP,__fatbin" :
".hipFatBinSegment")
305 : (
Triple.isMacOSX() ?
"__NV_CUDA,__fatbin" :
".nvFatBinSegment");
318 FatbinInitializer,
".fatbin_wrapper" + Suffix);
319 FatbinDesc->setSection(FatbinWrapperSection);
320 FatbinDesc->setAlignment(
Align(8));
321 FatbinDesc->setNoSanitizeMetadata();
355 bool EmitSurfacesAndTextures) {
357 auto [EntriesB, EntriesE] = EntryArray;
366 Int8PtrTy, Int8PtrTy, Int8PtrTy, Int8PtrTy, Int32PtrTy},
369 IsHIP ?
"__hipRegisterFunction" :
"__cudaRegisterFunction", RegFuncTy);
378 IsHIP ?
"__hipRegisterVar" :
"__cudaRegisterVar", RegVarTy);
383 {Int8PtrPtrTy, Int8PtrTy, Int8PtrTy, Int8PtrTy,
387 IsHIP ?
"__hipRegisterManagedVar" :
"__cudaRegisterManagedVar",
393 {Int8PtrPtrTy, Int8PtrTy, Int8PtrTy, Int8PtrTy,
397 IsHIP ?
"__hipRegisterSurface" :
"__cudaRegisterSurface", RegSurfaceTy);
406 IsHIP ?
"__hipRegisterTexture" :
"__cudaRegisterTexture", RegTextureTy);
412 IsHIP ?
".hip.globals_reg" :
".cuda.globals_reg", &M);
413 RegGlobalsFn->setSection(getStartupSection(M.getTargetTriple()));
428 auto *EntryCmp = Builder.CreateICmpNE(EntriesB, EntriesE);
429 Builder.CreateCondBr(EntryCmp, EntryBB, ExitBB);
430 Builder.SetInsertPoint(EntryBB);
436 auto *Addr = Builder.CreateLoad(Int8PtrTy, AddrPtr,
"addr");
441 auto *AuxAddr = Builder.CreateLoad(Int8PtrTy, AuxAddrPtr,
"aux_addr");
451 auto *
Name = Builder.CreateLoad(Int8PtrTy, NamePtr,
"name");
466 auto *
Data = Builder.CreateTrunc(
469 auto *
Type = Builder.CreateAnd(
473 auto *ExternBit = Builder.CreateAnd(
476 auto *
Extern = Builder.CreateLShr(
481 auto *
Const = Builder.CreateLShr(
483 auto *NormalizedBit = Builder.CreateAnd(
486 auto *Normalized = Builder.CreateLShr(
488 auto *KindCond = Builder.CreateICmpEQ(
492 Builder.CreateCondBr(KindCond, IfKindBB, IfEndBB);
493 Builder.SetInsertPoint(IfKindBB);
494 auto *FnCond = Builder.CreateICmpEQ(
496 Builder.CreateCondBr(FnCond, IfThenBB, IfElseBB);
499 Builder.SetInsertPoint(IfThenBB);
502 {RegGlobalsFn->arg_begin(), Addr,
Name,
Name,
507 Builder.CreateBr(IfEndBB);
508 Builder.SetInsertPoint(IfElseBB);
510 auto *
Switch = Builder.CreateSwitch(
Type, IfEndBB);
512 Builder.SetInsertPoint(SwGlobalBB);
513 Builder.CreateCall(RegVar,
516 Builder.CreateBr(IfEndBB);
521 Builder.SetInsertPoint(SwManagedBB);
522 Builder.CreateCall(RegManagedVar, {RegGlobalsFn->arg_begin(), AuxAddr, Addr,
524 Builder.CreateBr(IfEndBB);
528 Builder.SetInsertPoint(SwSurfaceBB);
529 if (EmitSurfacesAndTextures)
530 Builder.CreateCall(RegSurface, {RegGlobalsFn->arg_begin(), Addr,
Name,
Name,
532 Builder.CreateBr(IfEndBB);
537 Builder.SetInsertPoint(SwTextureBB);
538 if (EmitSurfacesAndTextures)
539 Builder.CreateCall(RegTexture, {RegGlobalsFn->arg_begin(), Addr,
Name,
Name,
541 Builder.CreateBr(IfEndBB);
545 Builder.SetInsertPoint(IfEndBB);
546 auto *NewEntry = Builder.CreateInBoundsGEP(
548 auto *
Cmp = Builder.CreateICmpEQ(NewEntry, EntriesE);
549 Entry->addIncoming(EntriesB, &RegGlobalsFn->getEntryBlock());
550 Entry->addIncoming(NewEntry, IfEndBB);
551 Builder.CreateCondBr(Cmp, ExitBB, EntryBB);
552 Builder.SetInsertPoint(ExitBB);
553 Builder.CreateRetVoid();
563 bool EmitSurfacesAndTextures) {
568 (IsHIP ?
".hip.fatbin_reg" :
".cuda.fatbin_reg") + Suffix, &M);
569 CtorFunc->setSection(getStartupSection(M.getTargetTriple()));
574 (IsHIP ?
".hip.fatbin_unreg" :
".cuda.fatbin_unreg") + Suffix, &M);
575 DtorFunc->setSection(getStartupSection(M.getTargetTriple()));
582 IsHIP ?
"__hipRegisterFatBinary" :
"__cudaRegisterFatBinary", RegFatTy);
587 M.getOrInsertFunction(
"__cudaRegisterFatBinaryEnd", RegFatEndTy);
592 IsHIP ?
"__hipUnregisterFatBinary" :
"__cudaUnregisterFatBinary",
597 FunctionCallee AtExit = M.getOrInsertFunction(
"atexit", AtExitTy);
602 (IsHIP ?
".hip.binary_handle" :
".cuda.binary_handle") + Suffix);
606 CallInst *Handle = CtorBuilder.CreateCall(
609 CtorBuilder.CreateAlignedStore(
610 Handle, BinaryHandleGlobal,
611 Align(M.getDataLayout().getPointerTypeSize(PtrTy)));
612 CtorBuilder.CreateCall(createRegisterGlobalsFunction(M, IsHIP, EntryArray,
614 EmitSurfacesAndTextures),
617 CtorBuilder.CreateCall(RegFatbinEnd, Handle);
618 CtorBuilder.CreateCall(AtExit, DtorFunc);
619 CtorBuilder.CreateRetVoid();
625 LoadInst *BinaryHandle = DtorBuilder.CreateAlignedLoad(
626 PtrTy, BinaryHandleGlobal,
627 Align(M.getDataLayout().getPointerTypeSize(PtrTy)));
628 DtorBuilder.CreateCall(UnregFatbin, BinaryHandle);
629 DtorBuilder.CreateRetVoid();
638 SYCLWrapper(
Module &M,
const SYCLJITOptions &Options)
639 : M(M), C(M.
getContext()), Options(Options) {}
644 std::pair<Constant *, Constant *> embedBinary(ArrayRef<char> Buffer) {
646 GlobalVariable *BinaryGV =
new GlobalVariable(
648 Arr,
".sycl_offloading.binary");
652 IntegerType *Int64Ty = Type::getInt64Ty(C);
660 void createRegisterFatbinFunction(Constant *Start, Constant *
Size) {
661 FunctionType *FuncTy =
662 FunctionType::get(Type::getVoidTy(C),
false);
664 Twine(
"sycl") +
".descriptor_reg", &M);
665 Func->setSection(getStartupSection(M.getTargetTriple()));
668 IntegerType *Int64Ty = Type::getInt64Ty(C);
669 FunctionType *RegFuncTy =
670 FunctionType::get(Type::getVoidTy(C), {PtrTy, Int64Ty},
672 FunctionCallee RegFuncC =
673 M.getOrInsertFunction(
"__sycl_register_lib", RegFuncTy);
676 Builder.CreateCall(RegFuncC, {
Start,
Size});
677 Builder.CreateRetVoid();
682 void createUnregisterFunction(Constant *Start, Constant *
Size) {
683 FunctionType *FuncTy =
684 FunctionType::get(Type::getVoidTy(C),
false);
686 "sycl.descriptor_unreg", &M);
687 Func->setSection(getStartupSection(M.getTargetTriple()));
690 IntegerType *Int64Ty = Type::getInt64Ty(C);
691 FunctionType *UnRegFuncTy =
692 FunctionType::get(Type::getVoidTy(C), {PtrTy, Int64Ty},
694 FunctionCallee UnRegFuncC =
695 M.getOrInsertFunction(
"__sycl_unregister_lib", UnRegFuncTy);
698 Builder.CreateCall(UnRegFuncC, {
Start,
Size});
699 Builder.CreateRetVoid();
707 SYCLJITOptions Options;
716 createBinDesc(M, Images, EntryArray, Suffix, Relocatable);
719 "No binary descriptors created.");
720 createRegisterFunction(M,
Desc, Suffix);
727 bool EmitSurfacesAndTextures) {
731 "No fatbin section created.");
733 createRegisterFatbinFunction(M,
Desc,
false, EntryArray, Suffix,
734 EmitSurfacesAndTextures);
740 bool EmitSurfacesAndTextures) {
744 "No fatbin section created.");
746 createRegisterFatbinFunction(M,
Desc,
true, EntryArray, Suffix,
747 EmitSurfacesAndTextures);
754 auto [Start,
Size] = W.embedBinary(Buffer);
755 W.createRegisterFatbinFunction(Start,
Size);
756 W.createUnregisterFunction(Start,
Size);
static IntegerType * getSizeTTy(IRBuilderBase &B, const TargetLibraryInfo *TLI)
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.
Machine Check Debug Module
This file defines the SmallVector class.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
size_t size() const
size - 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(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
static LLVM_ABI PointerType * get(Type *ElementType, unsigned AddressSpace)
This constructs a pointer to an object of the specified type 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.
StringRef - 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()
@ C
The default llvm calling convention, compatible with C.
@ 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 ...
LLVM_ABI llvm::Error wrapSYCLBinaries(llvm::Module &M, llvm::ArrayRef< char > Buffer, SYCLJITOptions Options=SYCLJITOptions())
Wraps OffloadBinaries in the given Buffers into the module M as global symbols and registers the imag...
@ 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 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< GlobalVariable *, GlobalVariable * > 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
Context & getContext() const
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.
FunctionAddr VTableAddr uintptr_t uintptr_t Data
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.
LLVM_ABI void appendToGlobalDtors(Module &M, Function *F, int Priority, Constant *Data=nullptr)
Same as appendToGlobalCtors(), but for global dtors.
@ 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.