3131#include " llvm/IR/LLVMContext.h"
3232#include " llvm/IR/Module.h"
3333#include " llvm/IR/PassManager.h"
34+ #include " llvm/SYCLLowerIR/ComputeModuleRuntimeInfo.h"
3435#include " llvm/TargetParser/Triple.h"
36+ #include < optional>
3537#ifndef NDEBUG
3638#include " llvm/IR/Verifier.h"
3739#endif // NDEBUG
@@ -366,6 +368,8 @@ class BinaryWrapper {
366368 // / Records all created memory buffers for safe auto-gc
367369 llvm::SmallVector<std::unique_ptr<MemoryBuffer>, 4 > AutoGcBufs;
368370
371+ std::optional<util::PropertySet> SYCLNativeCPUPropSet = std::nullopt ;
372+
369373public:
370374 void addImage (const OffloadKind Kind, llvm::StringRef File,
371375 llvm::StringRef Manif, llvm::StringRef Tgt,
@@ -649,16 +653,9 @@ class BinaryWrapper {
649653 }
650654
651655 Function *addDeclarationForNativeCPU (StringRef Name) {
652- static FunctionType *NativeCPUFuncTy = FunctionType::get (
656+ static FunctionType *FTy = FunctionType::get (
653657 Type::getVoidTy (C),
654658 {PointerType::getUnqual (C), PointerType::getUnqual (C)}, false );
655- static FunctionType *NativeCPUBuiltinTy = FunctionType::get (
656- PointerType::getUnqual (C), {PointerType::getUnqual (C)}, false );
657- FunctionType *FTy;
658- if (Name.starts_with (" __dpcpp_nativecpu" ))
659- FTy = NativeCPUBuiltinTy;
660- else
661- FTy = NativeCPUFuncTy;
662659 auto FCalle = M.getOrInsertFunction (
663660 sycl::utils::addSYCLNativeCPUSuffix (Name).str (), FTy);
664661 Function *F = dyn_cast<Function>(FCalle.getCallee ());
@@ -668,16 +665,27 @@ class BinaryWrapper {
668665 }
669666
670667 Expected<std::pair<Constant *, Constant *>>
671- addDeclarationsForNativeCPU (StringRef EntriesFile) {
668+ addDeclarationsForNativeCPU (StringRef EntriesFile, std::optional<util::PropertySet> NativeCPUProps ) {
672669 Expected<MemoryBuffer *> MBOrErr = loadFile (EntriesFile);
673670 if (!MBOrErr)
674671 return MBOrErr.takeError ();
675672 MemoryBuffer *MB = *MBOrErr;
676- // the Native CPU PI Plug-in expects the BinaryStart field to point to an
677- // array of struct nativecpu_entry {
673+ // the Native CPU UR adapter expects the BinaryStart field to point to
674+ //
675+ // struct nativecpu_program {
676+ // nativecpu_entry *entries;
677+ // ur_program_properties_t *properties;
678+ // };
679+ //
680+ // where "entries" is an array of:
681+ //
682+ // struct nativecpu_entry {
678683 // char *kernelname;
679684 // unsigned char *kernel_ptr;
680685 // };
686+ StructType *NCPUProgramT = StructType::create (
687+ {PointerType::getUnqual (C), PointerType::getUnqual (C)},
688+ " nativecpu_program" );
681689 StructType *NCPUEntryT = StructType::create (
682690 {PointerType::getUnqual (C), PointerType::getUnqual (C)},
683691 " __nativecpu_entry" );
@@ -703,12 +711,30 @@ class BinaryWrapper {
703711 auto *GVar = new GlobalVariable (M, CA->getType (), true ,
704712 GlobalVariable::InternalLinkage, CA,
705713 " __sycl_native_cpu_decls" );
706- auto *Begin = ConstantExpr::getGetElementPtr (GVar->getValueType (), GVar,
714+ auto *EntriesBegin = ConstantExpr::getGetElementPtr (GVar->getValueType (), GVar,
715+ getSizetConstPair (0u , 0u ));
716+ Constant *PropValue = NullPtr;
717+ if (NativeCPUProps.has_value ()) {
718+ auto PropsOrErr = addSYCLPropertySetToModule (*NativeCPUProps);
719+ if (!PropsOrErr)
720+ return PropsOrErr.takeError ();
721+ auto *Category = addStringToModule (sycl::PropSetRegTy::SYCL_NATIVE_CPU_PROPS, " SYCL_PropSetName" );
722+ auto S = ConstantStruct::get (
723+ getSyclPropSetTy (), Category, PropsOrErr.get ().first , PropsOrErr.get ().second );
724+ auto T = addStructArrayToModule ({S}, getSyclPropSetTy ());
725+ PropValue = T.first ;
726+ }
727+ auto *Program = ConstantStruct::get (NCPUProgramT, {EntriesBegin, PropValue});
728+ ArrayType *ProgramATy = ArrayType::get (NCPUProgramT, 1 );
729+ Constant *CPA = ConstantArray::get (ProgramATy, {Program});
730+ auto *ProgramGVar = new GlobalVariable (M, ProgramATy, true ,
731+ GlobalVariable::InternalLinkage, CPA,
732+ " __sycl_native_cpu_program" );
733+ auto *ProgramBegin = ConstantExpr::getGetElementPtr (ProgramGVar->getValueType (), ProgramGVar,
707734 getSizetConstPair (0u , 0u ));
708- auto *End = ConstantExpr::getGetElementPtr (
709- GVar->getValueType (), GVar,
710- getSizetConstPair (0u , NativeCPUEntries.size ()));
711- return std::make_pair (Begin, End);
735+ auto *ProgramEnd = ConstantExpr::getGetElementPtr (ProgramGVar->getValueType (), ProgramGVar,
736+ getSizetConstPair (0u , 1u ));
737+ return std::make_pair (ProgramBegin, ProgramEnd);
712738 }
713739
714740 // Adds a global readonly variable that is initialized by given data to the
@@ -941,6 +967,12 @@ class BinaryWrapper {
941967 // the PropSetsInits
942968 for (const auto &PropSet : *PropRegistry) {
943969 // create content in the rightmost column and get begin/end pointers
970+ if (PropSet.first == sycl::PropSetRegTy::SYCL_NATIVE_CPU_PROPS) {
971+ // We don't emit Native CPU specific properties in this section, but instead
972+ // we emit them in the native_cpu_entry struct directly.
973+ SYCLNativeCPUPropSet = PropSet.second ;
974+ continue ;
975+ }
944976 Expected<std::pair<Constant *, Constant *>> Props =
945977 addSYCLPropertySetToModule (PropSet.second );
946978 if (!Props)
@@ -1103,7 +1135,7 @@ class BinaryWrapper {
11031135 }
11041136 std::pair<Constant *, Constant *> Fbin;
11051137 if (Img.Tgt == " native_cpu" ) {
1106- auto FBinOrErr = addDeclarationsForNativeCPU (Img.EntriesFile );
1138+ auto FBinOrErr = addDeclarationsForNativeCPU (Img.EntriesFile , SYCLNativeCPUPropSet );
11071139 if (!FBinOrErr)
11081140 return FBinOrErr.takeError ();
11091141 Fbin = *FBinOrErr;
0 commit comments