-
Notifications
You must be signed in to change notification settings - Fork 795
[SYCL][NFC] Remove makeResultFilename function from sycl-post-link #17602
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
61156c2
010327e
d5c98cf
84ede89
4db209d
1908e08
f38baa8
1ada9b0
16a20bf
b2a994b
876d94d
075e633
d229ab0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -259,33 +259,18 @@ struct IrPropSymFilenameTriple { | |
| std::string Sym; | ||
| }; | ||
|
|
||
| void writeToFile(const std::string &Filename, const std::string &Content) { | ||
| static void writeToFile(const StringRef Filename, const StringRef Content) { | ||
| std::error_code EC; | ||
| raw_fd_ostream OS{Filename, EC, sys::fs::OpenFlags::OF_None}; | ||
| checkError(EC, "error opening the file '" + Filename + "'"); | ||
| OS.write(Content.data(), Content.size()); | ||
| OS.close(); | ||
| } | ||
|
|
||
| // Creates a filename based on current output filename, given extension, | ||
| // sequential ID and suffix. | ||
| std::string makeResultFileName(Twine Ext, int I, StringRef Suffix) { | ||
| const StringRef Dir0 = OutputDir.getNumOccurrences() > 0 | ||
| ? OutputDir | ||
| : sys::path::parent_path(OutputFiles[0].Filename); | ||
| const StringRef Sep = sys::path::get_separator(); | ||
| std::string Dir = Dir0.str(); | ||
| if (!Dir0.empty() && !Dir0.ends_with(Sep)) | ||
| Dir += Sep.str(); | ||
| return (Dir + sys::path::stem(OutputFiles[0].Filename) + Suffix + "_" + | ||
| Twine(I) + Ext) | ||
| .str(); | ||
| } | ||
|
|
||
| void saveModuleIR(Module &M, StringRef OutFilename) { | ||
| void saveModuleIR(Module &M, const StringRef Filename) { | ||
| std::error_code EC; | ||
| raw_fd_ostream Out{OutFilename, EC, sys::fs::OF_None}; | ||
| checkError(EC, "error opening the file '" + OutFilename + "'"); | ||
| raw_fd_ostream Out{Filename, EC, sys::fs::OF_None}; | ||
| checkError(EC, "error opening the file '" + Filename + "'"); | ||
|
|
||
| ModulePassManager MPM; | ||
| ModuleAnalysisManager MAM; | ||
|
|
@@ -298,17 +283,9 @@ void saveModuleIR(Module &M, StringRef OutFilename) { | |
| MPM.run(M, MAM); | ||
| } | ||
|
|
||
| std::string saveModuleIR(Module &M, int I, StringRef Suff) { | ||
| DUMP_ENTRY_POINTS(M, EmitOnlyKernelsAsEntryPoints, "saving IR"); | ||
| StringRef FileExt = (OutputAssembly) ? ".ll" : ".bc"; | ||
| std::string OutFilename = makeResultFileName(FileExt, I, Suff); | ||
| saveModuleIR(M, OutFilename); | ||
| return OutFilename; | ||
| } | ||
|
|
||
| std::string saveModuleProperties(module_split::ModuleDesc &MD, | ||
| const GlobalBinImageProps &GlobProps, int I, | ||
| StringRef Suff, StringRef Target = "") { | ||
| void saveModuleProperties(const module_split::ModuleDesc &MD, | ||
| const GlobalBinImageProps &GlobProps, | ||
| const StringRef Filename, StringRef Target = "") { | ||
|
|
||
| PropSetRegTy PropSet; | ||
|
|
||
|
|
@@ -331,35 +308,21 @@ std::string saveModuleProperties(module_split::ModuleDesc &MD, | |
| PropSet.remove(PropSetRegTy::SYCL_DEVICE_REQUIREMENTS, | ||
| PropSetRegTy::PROPERTY_REQD_WORK_GROUP_SIZE); | ||
|
|
||
| std::string NewSuff = Suff.str(); | ||
| if (!Target.empty()) { | ||
| if (!Target.empty()) | ||
| PropSet.add(PropSetRegTy::SYCL_DEVICE_REQUIREMENTS, "compile_target", | ||
| Target); | ||
| NewSuff += "_"; | ||
| NewSuff += Target; | ||
| } | ||
|
|
||
| std::error_code EC; | ||
| std::string SCFile = makeResultFileName(".prop", I, NewSuff); | ||
| raw_fd_ostream SCOut(SCFile, EC); | ||
| checkError(EC, "error opening file '" + SCFile + "'"); | ||
| raw_fd_ostream SCOut(Filename, EC); | ||
| checkError(EC, "error opening file '" + Filename + "'"); | ||
| PropSet.write(SCOut); | ||
|
|
||
| return SCFile; | ||
| } | ||
|
|
||
| // Saves specified collection of symbols to a file. | ||
| std::string saveModuleSymbolTable(const module_split::ModuleDesc &MD, int I, | ||
| StringRef Suffix) { | ||
| auto SymT = computeModuleSymbolTable(MD.getModule(), MD.entries()); | ||
| std::string OutFileName = makeResultFileName(".sym", I, Suffix); | ||
| writeToFile(OutFileName, SymT); | ||
| return OutFileName; | ||
| } | ||
|
|
||
| // Compute the filename suffix for the module | ||
| StringRef getModuleSuffix(const module_split::ModuleDesc &MD) { | ||
| return MD.isESIMD() ? "_esimd" : ""; | ||
| void saveModuleSymbolTable(const module_split::ModuleDesc &MD, | ||
| const StringRef Filename) { | ||
| std::string SymT = computeModuleSymbolTable(MD.getModule(), MD.entries()); | ||
| writeToFile(Filename, SymT); | ||
| } | ||
|
|
||
| bool isTargetCompatibleWithModule(const std::string &Target, | ||
|
|
@@ -368,35 +331,41 @@ bool isTargetCompatibleWithModule(const std::string &Target, | |
| void addTableRow(util::SimpleTable &Table, | ||
| const IrPropSymFilenameTriple &RowData); | ||
|
|
||
| // @param OutTables List of tables (one for each target) to output results | ||
| // @param MD Module descriptor to save | ||
| // @param IRFilename filename of already available IR component. If not empty, | ||
| // IR component saving is skipped, and this file name is recorded as such in | ||
| // the result. | ||
| void saveModule(std::vector<std::unique_ptr<util::SimpleTable>> &OutTables, | ||
| module_split::ModuleDesc &MD, int I, StringRef IRFilename) { | ||
| /// \param OutTables List of tables (one for each target) to output results | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is a 'target'?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| /// \param MD Module descriptor to save | ||
| /// \param OutputPrefix Prefix for all generated outputs. | ||
| /// \param IRFilename Filename of IR component. If filename is not empty, it | ||
| /// is recorded in the OutTable. Otherwise, a new file is created to save | ||
| /// the IR component, and the new name is recorded in the OutTable. | ||
| void saveModule( | ||
| const std::vector<std::unique_ptr<util::SimpleTable>> &OutTables, | ||
| module_split::ModuleDesc &MD, const int I, const Twine &OutputPrefix, | ||
| const StringRef IRFilename) { | ||
| IrPropSymFilenameTriple BaseTriple; | ||
| StringRef Suffix = getModuleSuffix(MD); | ||
| StringRef Suffix = MD.isESIMD() ? "_esimd" : ""; | ||
| MD.saveSplitInformationAsMetadata(); | ||
|
|
||
| if (!MD.isSYCLDeviceLib()) { | ||
| if (!IRFilename.empty()) { | ||
| // don't save IR, just record the filename | ||
| BaseTriple.Ir = IRFilename.str(); | ||
| } else { | ||
| if (!IRFilename.empty()) { | ||
| // Don't save IR, just record the filename. | ||
| BaseTriple.Ir = IRFilename.str(); | ||
| } else { | ||
| if (!MD.isSYCLDeviceLib()) { | ||
| // For deviceLib Modules, we don't need to do clean up and no entry-point | ||
| // is included. The module only includes a bunch of exported functions | ||
| // intended to be invoked by user's device modules. | ||
| MD.cleanup(AllowDeviceImageDependencies); | ||
| BaseTriple.Ir = saveModuleIR(MD.getModule(), I, Suffix); | ||
| } | ||
| } else { | ||
| // For deviceLib Modules, don't need to do clean up, no entry-point | ||
| // is included, the module only includes a bunch of exported functions | ||
| // intended to be invoked by user's device modules. | ||
| BaseTriple.Ir = saveModuleIR(MD.getModule(), I, Suffix); | ||
|
|
||
| StringRef IRExtension = OutputAssembly ? ".ll" : ".bc"; | ||
| BaseTriple.Ir = | ||
| (OutputPrefix + Suffix + "_" + Twine(I) + IRExtension).str(); | ||
| saveModuleIR(MD.getModule(), BaseTriple.Ir); | ||
| } | ||
|
|
||
| if (DoSymGen) { | ||
| // save the names of the entry points - the symbol table | ||
| BaseTriple.Sym = saveModuleSymbolTable(MD, I, Suffix); | ||
| // Save the names of the entry points - the symbol table. | ||
| BaseTriple.Sym = (OutputPrefix + Suffix + "_" + Twine(I) + ".sym").str(); | ||
| saveModuleSymbolTable(MD, BaseTriple.Sym); | ||
| } | ||
|
|
||
| for (const auto &[Table, OutputFile] : zip_equal(OutTables, OutputFiles)) { | ||
|
|
@@ -407,20 +376,31 @@ void saveModule(std::vector<std::unique_ptr<util::SimpleTable>> &OutTables, | |
| GlobalBinImageProps Props = {EmitKernelParamInfo, EmitProgramMetadata, | ||
| EmitKernelNames, EmitExportedSymbols, | ||
| EmitImportedSymbols, DeviceGlobals}; | ||
| StringRef Target = OutputFile.Target; | ||
| std::string NewSuff = Suffix.str(); | ||
| if (!Target.empty()) | ||
| NewSuff = (Twine("_") + Target).str(); | ||
|
|
||
| CopyTriple.Prop = | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Curious. Why do we not use DoPropGen flag here to guard 'saveModuleProperties'?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Looks like we do use the flag. |
||
| saveModuleProperties(MD, Props, I, Suffix, OutputFile.Target); | ||
| (OutputPrefix + NewSuff + "_" + Twine(I) + ".prop").str(); | ||
| saveModuleProperties(MD, Props, CopyTriple.Prop, Target); | ||
| } | ||
| addTableRow(*Table, CopyTriple); | ||
| } | ||
| } | ||
|
|
||
| void saveDeviceLibModule( | ||
| std::vector<std::unique_ptr<util::SimpleTable>> &OutTables, int I, | ||
| const std::vector<std::unique_ptr<util::SimpleTable>> &OutTables, | ||
| const Twine &OutputPrefix, const int I, | ||
| const std::string &DeviceLibFileName) { | ||
| assert(!DeviceLibFileName.empty() && | ||
| "DeviceLibFileName is expected to be non-empty."); | ||
| SMDiagnostic Err; | ||
| LLVMContext Context; | ||
| StringRef DeviceLibLoc = DeviceLibDir; | ||
| std::string DeviceLibPath = DeviceLibLoc.str() + "/" + DeviceLibFileName; | ||
| StringRef Sep = llvm::sys::path::get_separator(); | ||
| std::string DeviceLibPath = | ||
| (DeviceLibLoc.str() + Sep + DeviceLibFileName).str(); | ||
| std::unique_ptr<Module> DeviceLibIR = | ||
| parseIRFile(DeviceLibPath, Err, Context); | ||
| Module *DeviceLibMPtr = DeviceLibIR.get(); | ||
|
|
@@ -431,7 +411,7 @@ void saveDeviceLibModule( | |
| } | ||
| llvm::module_split::ModuleDesc DeviceLibMD(std::move(DeviceLibIR), | ||
| DeviceLibFileName); | ||
| saveModule(OutTables, DeviceLibMD, I, DeviceLibFileName); | ||
| saveModule(OutTables, DeviceLibMD, I, OutputPrefix, ""); | ||
| } | ||
|
|
||
| module_split::ModuleDesc link(module_split::ModuleDesc &&MD1, | ||
|
|
@@ -623,7 +603,7 @@ bool isTargetCompatibleWithModule(const std::string &Target, | |
| } | ||
|
|
||
| std::vector<std::unique_ptr<util::SimpleTable>> | ||
| processInputModule(std::unique_ptr<Module> M) { | ||
| processInputModule(std::unique_ptr<Module> M, const StringRef OutputPrefix) { | ||
| // Construct the resulting table which will accumulate all the outputs. | ||
| SmallVector<StringRef, MAX_COLUMNS_IN_FILE_TABLE> ColumnTitles{ | ||
| StringRef(COL_CODE)}; | ||
|
|
@@ -728,7 +708,7 @@ processInputModule(std::unique_ptr<Module> M) { | |
| } | ||
| for (module_split::ModuleDesc &IrMD : MMs) { | ||
| IsBF16DeviceLibUsed |= isSYCLDeviceLibBF16Used(IrMD.getModule()); | ||
| saveModule(Tables, IrMD, ID, OutIRFileName); | ||
| saveModule(Tables, IrMD, ID, OutputPrefix, OutIRFileName); | ||
| } | ||
|
|
||
| ++ID; | ||
|
|
@@ -737,20 +717,35 @@ processInputModule(std::unique_ptr<Module> M) { | |
| for (size_t i = 0; i != MMsWithDefaultSpecConsts.size(); ++i) { | ||
| module_split::ModuleDesc &IrMD = MMsWithDefaultSpecConsts[i]; | ||
| IsBF16DeviceLibUsed |= isSYCLDeviceLibBF16Used(IrMD.getModule()); | ||
| saveModule(Tables, IrMD, ID, OutIRFileName); | ||
| saveModule(Tables, IrMD, ID, OutputPrefix, OutIRFileName); | ||
| } | ||
|
|
||
| ++ID; | ||
| } | ||
| } | ||
|
|
||
| if (IsBF16DeviceLibUsed && (DeviceLibDir.getNumOccurrences() > 0)) { | ||
| saveDeviceLibModule(Tables, ID, "libsycl-fallback-bfloat16.bc"); | ||
| saveDeviceLibModule(Tables, ID + 1, "libsycl-native-bfloat16.bc"); | ||
| saveDeviceLibModule(Tables, OutputPrefix, ID, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It might be cleaner to populate a global constant with the list of device library module filenames and use that here? Ideally, it should be passed in as an option to sycl-post-link.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We could leave that for later. |
||
| "libsycl-fallback-bfloat16.bc"); | ||
| saveDeviceLibModule(Tables, OutputPrefix, ID + 1, | ||
| "libsycl-native-bfloat16.bc"); | ||
| } | ||
| return Tables; | ||
| } | ||
|
|
||
| /// Gets output prefix used for all output files from this tool. | ||
| std::string getOutputPrefix() { | ||
| StringRef Dir0 = OutputDir.getNumOccurrences() > 0 | ||
| ? OutputDir | ||
| : sys::path::parent_path(OutputFiles[0].Filename); | ||
| StringRef Sep = sys::path::get_separator(); | ||
| std::string Dir = Dir0.str(); | ||
| if (!Dir0.empty() && !Dir0.ends_with(Sep)) | ||
| Dir += Sep.str(); | ||
|
|
||
| return (Dir + sys::path::stem(OutputFiles[0].Filename)).str(); | ||
| } | ||
|
|
||
| } // namespace | ||
|
|
||
| int main(int argc, char **argv) { | ||
|
|
@@ -890,13 +885,13 @@ int main(int argc, char **argv) { | |
| } | ||
|
|
||
| if (OutputFiles.getNumOccurrences() == 0) { | ||
| StringRef S = | ||
| IROutputOnly ? (OutputAssembly ? ".out.ll" : "out.bc") : ".files"; | ||
| StringRef S = IROutputOnly ? ".out" : ".files"; | ||
| OutputFiles.push_back({{}, (sys::path::stem(InputFilename) + S).str()}); | ||
| } | ||
|
|
||
| std::string OutputPrefix = getOutputPrefix(); | ||
| std::vector<std::unique_ptr<util::SimpleTable>> Tables = | ||
| processInputModule(std::move(M)); | ||
| processInputModule(std::move(M), OutputPrefix); | ||
|
|
||
| // Input module was processed and a single output file was requested. | ||
| if (IROutputOnly) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
MPM.runwould not accept a const reference.