1212// - module splitter to split a big input module into smaller ones
1313// - specialization constant intrinsic transformation
1414// ===----------------------------------------------------------------------===//
15-
1615#include " llvm/ADT/SmallSet.h"
1716#include " llvm/ADT/StringRef.h"
1817#include " llvm/Analysis/AssumptionCache.h"
@@ -311,9 +310,20 @@ std::string saveModuleIR(Module &M, int I, StringRef Suff) {
311310
312311std::string saveModuleProperties (module_split::ModuleDesc &MD,
313312 const GlobalBinImageProps &GlobProps, int I,
314- StringRef Suff, StringRef Target = " " ) {
315- auto PropSet =
316- computeModuleProperties (MD.getModule (), MD.entries (), GlobProps);
313+ StringRef Suff, StringRef Target = " " ,
314+ bool IsDeviceLib = false ) {
315+ PropSetRegTy PropSet;
316+
317+ // For fallback devicelib module, no kernel included and no specialization
318+ // constant used, skip regular Prop emit.
319+ if (!IsDeviceLib)
320+ PropSet = computeModuleProperties (MD.getModule (), MD.entries (), GlobProps);
321+ else {
322+ auto SYCLDeviceLibMeta = getSYCLDeviceLibMeta (MD.Name );
323+ std::map<StringRef, unsigned int > RMEntry = {
324+ {" DeviceLibMetaData" , SYCLDeviceLibMeta}};
325+ PropSet.add (PropSetRegTy::SYCL_DEVICELIB_METADATA, RMEntry);
326+ }
317327
318328 std::string NewSuff = Suff.str ();
319329 if (!Target.empty ()) {
@@ -421,17 +431,24 @@ void addTableRow(util::SimpleTable &Table,
421431// IR component saving is skipped, and this file name is recorded as such in
422432// the result.
423433void saveModule (std::vector<std::unique_ptr<util::SimpleTable>> &OutTables,
424- module_split::ModuleDesc &MD, int I, StringRef IRFilename) {
434+ module_split::ModuleDesc &MD, int I, StringRef IRFilename,
435+ bool IsDeviceLib = false ) {
425436 IrPropSymFilenameTriple BaseTriple;
426437 StringRef Suffix = getModuleSuffix (MD);
427438 MD.saveSplitInformationAsMetadata ();
428- if (!IRFilename.empty ()) {
429- // don't save IR, just record the filename
430- BaseTriple.Ir = IRFilename.str ();
439+ if (!IsDeviceLib) {
440+ if (!IRFilename.empty ()) {
441+ // don't save IR, just record the filename
442+ BaseTriple.Ir = IRFilename.str ();
443+ } else {
444+ MD.cleanup ();
445+ BaseTriple.Ir = saveModuleIR (MD.getModule (), I, Suffix);
446+ }
431447 } else {
432- MD. cleanup ();
448+ // For DeviceLib Modules, don't need to do clean up.
433449 BaseTriple.Ir = saveModuleIR (MD.getModule (), I, Suffix);
434450 }
451+
435452 if (DoSymGen) {
436453 // save the names of the entry points - the symbol table
437454 BaseTriple.Sym = saveModuleSymbolTable (MD, I, Suffix);
@@ -445,13 +462,24 @@ void saveModule(std::vector<std::unique_ptr<util::SimpleTable>> &OutTables,
445462 GlobalBinImageProps Props = {EmitKernelParamInfo, EmitProgramMetadata,
446463 EmitExportedSymbols, EmitImportedSymbols,
447464 DeviceGlobals};
448- CopyTriple.Prop =
449- saveModuleProperties (MD, Props, I, Suffix, OutputFile.Target );
465+ CopyTriple.Prop = saveModuleProperties (MD, Props, I, Suffix,
466+ OutputFile.Target , IsDeviceLib );
450467 }
451468 addTableRow (*Table, CopyTriple);
452469 }
453470}
454471
472+ void saveDeviceLibModule (
473+ std::vector<std::unique_ptr<util::SimpleTable>> &OutTables,
474+ const std::string &IRFile, int I, LLVMContext &Context) {
475+ SMDiagnostic Err;
476+ StringRef DeviceLibLoc = DeviceLibDir;
477+ std::string IRPath = DeviceLibLoc.str () + " /" + IRFile;
478+ std::unique_ptr<Module> IRModule = parseIRFile (IRPath, Err, Context);
479+ llvm::module_split::ModuleDesc LibIRMD (std::move (IRModule), IRFile);
480+ saveModule (OutTables, LibIRMD, I, IRFile, true );
481+ }
482+
455483module_split::ModuleDesc link (module_split::ModuleDesc &&MD1,
456484 module_split::ModuleDesc &&MD2) {
457485 std::vector<std::string> Names;
@@ -747,7 +775,7 @@ bool isTargetCompatibleWithModule(const std::string &Target,
747775}
748776
749777std::vector<std::unique_ptr<util::SimpleTable>>
750- processInputModule (std::unique_ptr<Module> M) {
778+ processInputModule (std::unique_ptr<Module> M, LLVMContext &Context ) {
751779 // Construct the resulting table which will accumulate all the outputs.
752780 SmallVector<StringRef, MAX_COLUMNS_IN_FILE_TABLE> ColumnTitles{
753781 StringRef (COL_CODE)};
@@ -776,6 +804,9 @@ processInputModule(std::unique_ptr<Module> M) {
776804 // if none were made.
777805 bool Modified = false ;
778806
807+ // Keeps track of required device libraries by all device images.
808+ unsigned int DeviceLibReqMask = 0 ;
809+
779810 // Propagate ESIMD attribute to wrapper functions to prevent
780811 // spurious splits and kernel link errors.
781812 Modified |= runModulePass<SYCLFixupESIMDKernelWrapperMDPass>(*M);
@@ -887,6 +918,7 @@ processInputModule(std::unique_ptr<Module> M) {
887918 " have been made\n " ;
888919 }
889920 for (module_split::ModuleDesc &IrMD : MMs) {
921+ DeviceLibReqMask |= getSYCLDeviceLibReqMask (IrMD.getModule ());
890922 saveModule (Tables, IrMD, ID, OutIRFileName);
891923 }
892924
@@ -895,12 +927,22 @@ processInputModule(std::unique_ptr<Module> M) {
895927 if (!MMsWithDefaultSpecConsts.empty ()) {
896928 for (size_t i = 0 ; i != MMsWithDefaultSpecConsts.size (); ++i) {
897929 module_split::ModuleDesc &IrMD = MMsWithDefaultSpecConsts[i];
930+ DeviceLibReqMask |= getSYCLDeviceLibReqMask (IrMD.getModule ());
898931 saveModule (Tables, IrMD, ID, OutIRFileName);
899932 }
900933
901934 ++ID;
902935 }
903936 }
937+
938+ if ((DeviceLibReqMask > 0 ) && (DeviceLibDir.getNumOccurrences () > 0 )) {
939+ string_vector DeviceLibReqNames;
940+ getSYCLDeviceLibReqNames (DeviceLibReqMask, DeviceLibReqNames);
941+ for (auto Fn : DeviceLibReqNames) {
942+ saveDeviceLibModule (Tables, Fn, ID, Context);
943+ ++ID;
944+ }
945+ }
904946 return Tables;
905947}
906948
@@ -1044,7 +1086,7 @@ int main(int argc, char **argv) {
10441086 }
10451087
10461088 std::vector<std::unique_ptr<util::SimpleTable>> Tables =
1047- processInputModule (std::move (M));
1089+ processInputModule (std::move (M), Context );
10481090
10491091 // Input module was processed and a single output file was requested.
10501092 if (IROutputOnly)
0 commit comments