[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/hip commit: cc59af5dbd]
This commit is contained in:
emankov
2018-12-22 00:47:19 +03:00
parent c2b8bfb437
commit f8f00472f8
3 changed files with 77 additions and 36 deletions
@@ -29,6 +29,16 @@ cl::opt<std::string> OutputFilename("o",
cl::value_desc("filename"),
cl::cat(ToolTemplateCategory));
cl::opt<std::string> TemporaryDir("temp-dir",
cl::desc("Temporary direcory"),
cl::value_desc("directory"),
cl::cat(ToolTemplateCategory));
cl::opt <bool> SaveTemps("save-temps",
cl::desc("Save temporary files"),
cl::value_desc("save-temps"),
cl::cat(ToolTemplateCategory));
cl::opt <bool> TranslateToRoc("roc",
cl::desc("Translate to roc instead of hip where it is possible"),
cl::value_desc("roc"),
+2
View File
@@ -30,7 +30,9 @@ namespace ct = clang::tooling;
extern cl::OptionCategory ToolTemplateCategory;
extern cl::opt<std::string> OutputFilename;
extern cl::opt<std::string> TemporaryDir;
extern cl::opt<bool> Inplace;
extern cl::opt<bool> SaveTemps;
extern cl::opt<bool> NoBackup;
extern cl::opt<bool> NoOutput;
extern cl::opt<bool> PrintStats;
+65 -36
View File
@@ -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 <cstdio>
#include <fstream>
@@ -47,25 +42,54 @@ int main(int argc, const char **argv) {
llcompat::PrintStackTraceOnErrorSignal();
ct::CommonOptionsParser OptionsParser(argc, argv, ToolTemplateCategory, llvm::cl::OneOrMore);
std::vector<std::string> 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<std::ostream> 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<HipifyAction> 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();