75
75
using namespace llvm ;
76
76
77
77
using string_vector = std::vector<std::string>;
78
+ using PropSetRegTy = llvm::util::PropertySetRegistry;
78
79
79
80
namespace {
80
81
@@ -251,6 +252,11 @@ cl::opt<bool> GenerateDeviceImageWithDefaultSpecConsts{
251
252
" replaced with default values from specialization id(s)." ),
252
253
cl::cat (PostLinkCat)};
253
254
255
+ cl::opt<bool > EmbedAuxillaryInfoAsMetadata{
256
+ " embed-aux-info-as-metadata" ,
257
+ cl::desc (" Embed the module properties and symbols as metadata" ),
258
+ cl::cat (PostLinkCat)};
259
+
254
260
struct GlobalBinImageProps {
255
261
bool EmitKernelParamInfo;
256
262
bool EmitProgramMetadata;
@@ -393,10 +399,31 @@ std::string makeResultFileName(Twine Ext, int I, StringRef Suffix) {
393
399
.str ();
394
400
}
395
401
396
- void saveModuleIR (Module &M, StringRef OutFilename) {
402
+ // Add the module properties and symbol table as metadata. This is used when we
403
+ // compile with thinLTO, as sycl-post-link is run early.
404
+ void addAuxInfoAsMetadata (Module &M, const PropSetRegTy &PropSet,
405
+ const std::string &SymT) {
406
+ auto AddMD = [&M](StringRef MDName, const std::string &MDVal) {
407
+ auto NamedMD = M.getOrInsertNamedMetadata (MDName);
408
+ auto MDStr = MDString::get (M.getContext (), MDVal);
409
+ SmallVector<Metadata *, 2 > MD{MDStr};
410
+ auto MDOp = MDNode::get (M.getContext (), MD);
411
+ NamedMD->addOperand (MDOp);
412
+ };
413
+ std::string Buf;
414
+ raw_string_ostream OStr (Buf);
415
+ PropSet.write (OStr);
416
+ AddMD (" sycl_properties" , Buf);
417
+ AddMD (" sycl_symbol_table" , SymT);
418
+ }
419
+
420
+ void saveModuleIR (Module &M, StringRef OutFilename, const PropSetRegTy &PropSet,
421
+ const std::string &SymT) {
397
422
std::error_code EC;
398
423
raw_fd_ostream Out{OutFilename, EC, sys::fs::OF_None};
399
424
checkError (EC, " error opening the file '" + OutFilename + " '" );
425
+ if (EmbedAuxillaryInfoAsMetadata)
426
+ addAuxInfoAsMetadata (M, PropSet, SymT);
400
427
401
428
ModulePassManager MPM;
402
429
ModuleAnalysisManager MAM;
@@ -409,11 +436,12 @@ void saveModuleIR(Module &M, StringRef OutFilename) {
409
436
MPM.run (M, MAM);
410
437
}
411
438
412
- std::string saveModuleIR (Module &M, int I, StringRef Suff) {
439
+ std::string saveModuleIR (Module &M, int I, StringRef Suff,
440
+ const PropSetRegTy &PropSet, const std::string &SymT) {
413
441
DUMP_ENTRY_POINTS (M, EmitOnlyKernelsAsEntryPoints, " saving IR" );
414
442
StringRef FileExt = (OutputAssembly) ? " .ll" : " .bc" ;
415
443
std::string OutFilename = makeResultFileName (FileExt, I, Suff);
416
- saveModuleIR (M, OutFilename);
444
+ saveModuleIR (M, OutFilename, PropSet, SymT );
417
445
return OutFilename;
418
446
}
419
447
@@ -436,10 +464,8 @@ bool isImportedFunction(const Function &F) {
436
464
return ReturnValue;
437
465
}
438
466
439
- std::string saveModuleProperties (module_split::ModuleDesc &MD,
440
- const GlobalBinImageProps &GlobProps, int I,
441
- StringRef Suff) {
442
- using PropSetRegTy = llvm::util::PropertySetRegistry;
467
+ PropSetRegTy getModuleProperties (module_split::ModuleDesc &MD,
468
+ const GlobalBinImageProps &GlobProps) {
443
469
PropSetRegTy PropSet;
444
470
Module &M = MD.getModule ();
445
471
{
@@ -646,6 +672,14 @@ std::string saveModuleProperties(module_split::ModuleDesc &MD,
646
672
PropSet.add (PropSetRegTy::SYCL_MISC_PROP, " specConstsReplacedWithDefault" ,
647
673
1 );
648
674
675
+ return PropSet;
676
+ }
677
+
678
+ std::string saveModuleProperties (module_split::ModuleDesc &MD,
679
+ const GlobalBinImageProps &GlobProps,
680
+ const PropSetRegTy &PropSet, int I,
681
+ StringRef Suff) {
682
+
649
683
std::error_code EC;
650
684
std::string SCFile = makeResultFileName (" .prop" , I, Suff);
651
685
raw_fd_ostream SCOut (SCFile, EC);
@@ -655,9 +689,7 @@ std::string saveModuleProperties(module_split::ModuleDesc &MD,
655
689
return SCFile;
656
690
}
657
691
658
- // Saves specified collection of symbols to a file.
659
- std::string saveModuleSymbolTable (const module_split::EntryPointSet &Es, int I,
660
- StringRef Suffix) {
692
+ std::string getModuleSymbolTable (const module_split::EntryPointSet &Es) {
661
693
#ifndef NDEBUG
662
694
if (DebugPostLink > 0 ) {
663
695
llvm::errs () << " ENTRY POINTS saving Sym table {\n " ;
@@ -673,6 +705,12 @@ std::string saveModuleSymbolTable(const module_split::EntryPointSet &Es, int I,
673
705
for (const auto *F : Es) {
674
706
SymT = (Twine (SymT) + Twine (F->getName ()) + Twine (" \n " )).str ();
675
707
}
708
+ return SymT;
709
+ }
710
+
711
+ // Saves specified collection of symbols to a file.
712
+ std::string saveModuleSymbolTable (const std::string &SymT, int I,
713
+ StringRef Suffix) {
676
714
// Save to file.
677
715
std::string OutFileName = makeResultFileName (" .sym" , I, Suffix);
678
716
writeToFile (OutFileName, SymT);
@@ -757,22 +795,28 @@ IrPropSymFilenameTriple saveModule(module_split::ModuleDesc &MD, int I,
757
795
StringRef IRFilename = " " ) {
758
796
IrPropSymFilenameTriple Res;
759
797
StringRef Suffix = getModuleSuffix (MD);
760
-
798
+ GlobalBinImageProps Props = {EmitKernelParamInfo, EmitProgramMetadata,
799
+ EmitExportedSymbols, EmitImportedSymbols,
800
+ DeviceGlobals};
801
+ PropSetRegTy PropSet = getModuleProperties (MD, Props);
802
+ std::string SymT = getModuleSymbolTable (MD.entries ());
761
803
if (!IRFilename.empty ()) {
762
804
// don't save IR, just record the filename
763
805
Res.Ir = IRFilename.str ();
764
806
} else {
765
807
MD.cleanup ();
766
- Res.Ir = saveModuleIR (MD.getModule (), I, Suffix);
808
+ Res.Ir = saveModuleIR (MD.getModule (), I, Suffix, PropSet, SymT );
767
809
}
768
- GlobalBinImageProps Props = {EmitKernelParamInfo, EmitProgramMetadata,
769
- EmitExportedSymbols, EmitImportedSymbols,
770
- DeviceGlobals};
771
- Res.Prop = saveModuleProperties (MD, Props, I, Suffix);
772
-
773
- if (DoSymGen) {
810
+ // We don't need a seperate file with properties if we saved it as
811
+ // metadata inside the module itself.
812
+ if (!EmbedAuxillaryInfoAsMetadata)
813
+ Res.Prop = saveModuleProperties (MD, Props, PropSet, I, Suffix);
814
+
815
+ // Only save the symbol table to a seperate module if it
816
+ // was requested and was not placed inside the module itself.
817
+ if (DoSymGen && !EmbedAuxillaryInfoAsMetadata) {
774
818
// save the names of the entry points - the symbol table
775
- Res.Sym = saveModuleSymbolTable (MD. entries () , I, Suffix);
819
+ Res.Sym = saveModuleSymbolTable (SymT , I, Suffix);
776
820
}
777
821
return Res;
778
822
}
@@ -1071,10 +1115,12 @@ std::vector<std::unique_ptr<util::SimpleTable>>
1071
1115
processInputModule (std::unique_ptr<Module> M) {
1072
1116
// Construct the resulting table which will accumulate all the outputs.
1073
1117
SmallVector<StringRef, MAX_COLUMNS_IN_FILE_TABLE> ColumnTitles{
1074
- StringRef (COL_CODE), StringRef (COL_PROPS)};
1075
-
1076
- if (DoSymGen) {
1077
- ColumnTitles.push_back (COL_SYM);
1118
+ StringRef (COL_CODE)};
1119
+ if (!EmbedAuxillaryInfoAsMetadata) {
1120
+ ColumnTitles.push_back (COL_PROPS);
1121
+ if (DoSymGen) {
1122
+ ColumnTitles.push_back (COL_SYM);
1123
+ }
1078
1124
}
1079
1125
Expected<std::unique_ptr<util::SimpleTable>> TableE =
1080
1126
util::SimpleTable::create (ColumnTitles);
@@ -1185,7 +1231,13 @@ processInputModule(std::unique_ptr<Module> M) {
1185
1231
" ' can't be used" );
1186
1232
}
1187
1233
MMs.front ().cleanup ();
1188
- saveModuleIR (MMs.front ().getModule (), OutputFiles[0 ].Filename );
1234
+ const auto &ModuleProps = getModuleProperties (
1235
+ MMs.front (),
1236
+ {EmitKernelParamInfo, EmitProgramMetadata, EmitExportedSymbols,
1237
+ EmitImportedSymbols, DeviceGlobals});
1238
+ std::string SymT = getModuleSymbolTable (MMs.front ().entries ());
1239
+ saveModuleIR (MMs.front ().getModule (), OutputFiles[0 ].Filename ,
1240
+ ModuleProps, SymT);
1189
1241
return Tables;
1190
1242
}
1191
1243
// Empty IR file name directs saveModule to generate one and save IR to
@@ -1338,6 +1390,10 @@ int main(int argc, char **argv) {
1338
1390
return 1 ;
1339
1391
}
1340
1392
1393
+ if (!DoSymGen && EmbedAuxillaryInfoAsMetadata)
1394
+ errs () << " error: -" << EmbedAuxillaryInfoAsMetadata.ArgStr
1395
+ << " can't be used without -" << DoSymGen.ArgStr << " \n " ;
1396
+
1341
1397
SMDiagnostic Err;
1342
1398
std::unique_ptr<Module> M = parseIRFile (InputFilename, Err, Context);
1343
1399
// It is OK to use raw pointer here as we control that it does not outlive M
0 commit comments