From 0056b8ad20da663108b6c7c08c02bb07060bca09 Mon Sep 17 00:00:00 2001 From: emankov Date: Sat, 22 Dec 2018 00:47:19 +0300 Subject: [PATCH] [HIPIFY][#812] Finishing with temps 1. Option -temp-dir for temporary directory: + if not specified system temp is used; + creates the directory if the directory doesn't exist (only one level in a tree); + reports an error in case of a wrong directory specified, in case of necessity of creating a tree of subfolders, or in case of a filename specified. 2. Option -save-temps for preserving temporary files: + if specified temporary files are not being deleted from system temps and user temps as well. 3. Work with files in terms of calculated absolute paths by collapsing all '.' and '..' patterns, resolving symlinks and expanding '~' expression to the user's home directory: + to produce correct include paths; + to avoid possible errors on file routines. [ROCm/clr commit: 7cac7dbfea7c9a8890de7964432dc0d133480c00] --- .../clr/hipamd/hipify-clang/src/ArgParse.cpp | 10 ++ .../clr/hipamd/hipify-clang/src/ArgParse.h | 2 + projects/clr/hipamd/hipify-clang/src/main.cpp | 101 +++++++++++------- 3 files changed, 77 insertions(+), 36 deletions(-) diff --git a/projects/clr/hipamd/hipify-clang/src/ArgParse.cpp b/projects/clr/hipamd/hipify-clang/src/ArgParse.cpp index 971d5d1ee0..87aa8b6755 100644 --- a/projects/clr/hipamd/hipify-clang/src/ArgParse.cpp +++ b/projects/clr/hipamd/hipify-clang/src/ArgParse.cpp @@ -29,6 +29,16 @@ cl::opt OutputFilename("o", cl::value_desc("filename"), cl::cat(ToolTemplateCategory)); +cl::opt TemporaryDir("temp-dir", + cl::desc("Temporary direcory"), + cl::value_desc("directory"), + cl::cat(ToolTemplateCategory)); + +cl::opt SaveTemps("save-temps", + cl::desc("Save temporary files"), + cl::value_desc("save-temps"), + cl::cat(ToolTemplateCategory)); + cl::opt TranslateToRoc("roc", cl::desc("Translate to roc instead of hip where it is possible"), cl::value_desc("roc"), diff --git a/projects/clr/hipamd/hipify-clang/src/ArgParse.h b/projects/clr/hipamd/hipify-clang/src/ArgParse.h index d1e7e1a65a..efffe9e5de 100644 --- a/projects/clr/hipamd/hipify-clang/src/ArgParse.h +++ b/projects/clr/hipamd/hipify-clang/src/ArgParse.h @@ -30,7 +30,9 @@ namespace ct = clang::tooling; extern cl::OptionCategory ToolTemplateCategory; extern cl::opt OutputFilename; +extern cl::opt TemporaryDir; extern cl::opt Inplace; +extern cl::opt SaveTemps; extern cl::opt NoBackup; extern cl::opt NoOutput; extern cl::opt PrintStats; diff --git a/projects/clr/hipamd/hipify-clang/src/main.cpp b/projects/clr/hipamd/hipify-clang/src/main.cpp index a165ec31e9..5417dda783 100644 --- a/projects/clr/hipamd/hipify-clang/src/main.cpp +++ b/projects/clr/hipamd/hipify-clang/src/main.cpp @@ -19,11 +19,6 @@ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -/** - * @file Cuda2Hip.cpp - * - * This file is compiled and linked into clang based hipify tool. - */ #include #include @@ -47,25 +42,54 @@ int main(int argc, const char **argv) { llcompat::PrintStackTraceOnErrorSignal(); ct::CommonOptionsParser OptionsParser(argc, argv, ToolTemplateCategory, llvm::cl::OneOrMore); std::vector fileSources = OptionsParser.getSourcePathList(); - std::string dst = OutputFilename; - if (!dst.empty() && fileSources.size() > 1) { - llvm::errs() << "[HIPIFY] conflict: -o and multiple source files are specified.\n"; - return 1; - } - if (NoOutput) { + std::string dst = OutputFilename, sHipify = "[HIPIFY] ", sConflict = "conflict: ", sError = "error: "; + if (!dst.empty()) { + if (fileSources.size() > 1) { + llvm::errs() << sHipify << sConflict << "-o and multiple source files are specified.\n"; + return 1; + } if (Inplace) { - llvm::errs() << "[HIPIFY] conflict: both -no-output and -inplace options are specified.\n"; + llvm::errs() << sHipify << sConflict << "both -o and -inplace options are specified.\n"; return 1; } - if (!dst.empty()) { - llvm::errs() << "[HIPIFY] conflict: both -no-output and -o options are specified.\n"; + if (NoOutput) { + llvm::errs() << sHipify << sConflict << "both -no-output and -o options are specified.\n"; return 1; } } + if (NoOutput && Inplace) { + llvm::errs() << sHipify << sConflict << "both -no-output and -inplace options are specified.\n"; + return 1; + } if (Examine) { NoOutput = PrintStats = true; } int Result = 0; + std::error_code EC; + SmallString<128> tmpFile; + SmallString<256> sourceAbsPath, tmpDirAbsPath; + StringRef sourceFileName, sourceDir, ext = "hip"; + std::string sTmpDirAbsParh, sTmpFileName; + if (!TemporaryDir.empty()) { + EC = sys::fs::real_path(TemporaryDir, tmpDirAbsPath, true); + if (!EC && sys::fs::is_regular_file(tmpDirAbsPath)) { + llvm::errs() << "\n" << sHipify << sError << TemporaryDir << " is not a directory\n"; + return 1; + } + if (EC) { + EC = sys::fs::create_directory(TemporaryDir); + if (EC) { + llvm::errs() << "\n" << sHipify << sError << EC.message() << ": temporary directory: " << TemporaryDir << "\n"; + return 1; + } + EC = sys::fs::real_path(TemporaryDir, tmpDirAbsPath, true); + if (EC) { + llvm::errs() << "\n" << sHipify << sError << EC.message() << ": temporary directory: " << TemporaryDir << "\n"; + return 1; + } + } + sTmpDirAbsParh = tmpDirAbsPath.c_str(); + } // Arguments for the Statistics print routines. std::unique_ptr csv = nullptr; llvm::raw_ostream* statPrint = nullptr; @@ -75,39 +99,41 @@ int main(int argc, const char **argv) { if (PrintStats) { statPrint = &llvm::errs(); } + int FD; for (const auto & src : fileSources) { if (dst.empty()) { if (Inplace) { dst = src; } else { - dst = src + ".hip"; + dst = src + "." + ext.str(); } - } else if (Inplace) { - llvm::errs() << "[HIPIFY] conflict: both -o and -inplace options are specified.\n"; - return 1; } // Create a copy of the file to work on. When we're done, we'll move this onto the // output (which may mean overwriting the input, if we're in-place). // Should we fail for some reason, we'll just leak this file and not corrupt the input. - SmallString<128> tmpFile; - int FD; - StringRef Extension = "hipified-tmp"; - std::error_code EC = sys::fs::createTemporaryFile("hipify-clang", Extension, FD, tmpFile); + EC = sys::fs::real_path(src, sourceAbsPath, true); if (EC) { - llvm::errs() << EC.message() << "\n"; - return 1; + llvm::errs() << "\n" << sHipify << sError << EC.message() << ": " << src << "\n"; + Result = 1; + continue; } - SmallString<256> sourceAbsPath; - EC = sys::fs::real_path(src.c_str(), sourceAbsPath, true); - if (EC) { - llvm::errs() << EC.message() << "\n"; - return 1; + if (TemporaryDir.empty()) { + EC = sys::fs::createTemporaryFile(src, ext, FD, tmpFile); + if (EC) { + llvm::errs() << "\n" << sHipify << sError << EC.message() << ": " << tmpFile << "\n"; + Result = 1; + continue; + } + } else { + sourceFileName = sys::path::filename(sourceAbsPath); + sTmpFileName = sTmpDirAbsParh + "/" + sourceFileName.str() + "." + ext.str(); + tmpFile = sTmpFileName; } - StringRef sourceDir = sys::path::parent_path(sourceAbsPath); EC = sys::fs::copy_file(src, tmpFile); if (EC) { - llvm::errs() << EC.message() << "\n"; - return 1; + llvm::errs() << "\n" << sHipify << sError << EC.message() << ": while copying " << src << " to " << tmpFile << "\n"; + Result = 1; + continue; } // Initialise the statistics counters for this file. Statistics::setActive(src); @@ -117,7 +143,7 @@ int main(int argc, const char **argv) { ct::RefactoringTool Tool(OptionsParser.getCompilations(), std::string(tmpFile.c_str())); ct::Replacements& replacementsToUse = llcompat::getReplacements(Tool, tmpFile.c_str()); ReplacementsFrontendActionFactory actionFactory(&replacementsToUse); - std::string sInclude = "-I" + sourceDir.str(); + std::string sInclude = "-I" + sys::path::parent_path(sourceAbsPath).str(); Tool.appendArgumentsAdjuster(ct::getInsertArgumentAdjuster(sInclude.c_str(), ct::ArgumentInsertPosition::BEGIN)); Tool.appendArgumentsAdjuster(ct::getInsertArgumentAdjuster("--cuda-host-only", ct::ArgumentInsertPosition::BEGIN)); // Ensure at least c++11 is used. @@ -136,12 +162,15 @@ int main(int argc, const char **argv) { if (!NoOutput && !currentStat.hasErrors) { EC = sys::fs::copy_file(tmpFile, dst); if (EC) { - llvm::errs() << EC.message() << "\n"; - return 1; + llvm::errs() << "\n" << sHipify << sError << EC.message() << ": while copying " << tmpFile << " to " << dst << "\n"; + Result = 1; + continue; } } // Remove the tmp file without error check - sys::fs::remove(tmpFile); + if (!SaveTemps) { + sys::fs::remove(tmpFile); + } Statistics::current().markCompletion(); Statistics::current().print(csv.get(), statPrint); dst.clear();