diff --git a/hipify-clang/CMakeLists.txt b/hipify-clang/CMakeLists.txt index 1aaa68097f..355b0cea7a 100644 --- a/hipify-clang/CMakeLists.txt +++ b/hipify-clang/CMakeLists.txt @@ -1,63 +1,63 @@ cmake_minimum_required(VERSION 2.8.8) project(hipify-clang) -if (PARENT_SCOPE) - set(BUILD_HIPIFY_CLANG 0 PARENT_SCOPE) +option(HIPIFY_CLANG_TESTS "Build the tests for hipify-clang, if lit is installed" ON) + +# Disable the tests if `lit` is not installed. +find_program(LIT_COMMAND lit) +if (NOT LIT_COMMAND) + set(HIPIFY_CLANG_TESTS OFF CACHE INTERNAL "") + message(STATUS "hipify-clang's tests are not being built because `lit` is not installed.") endif() -# Find LLVM package -find_package(LLVM 3.8 QUIET PATHS ${HIPIFY_CLANG_LLVM_DIR} NO_DEFAULT_PATH) -if (NOT ${LLVM_FOUND}) - find_package(LLVM 3.9 QUIET PATHS ${HIPIFY_CLANG_LLVM_DIR} NO_DEFAULT_PATH) - if (NOT ${LLVM_FOUND}) - message(STATUS "hipify-clang will not be built. To build it please specify absolute path to LLVM 3.8 or LLVM 3.9 package/dist using -DHIPIFY_CLANG_LLVM_DIR") - endif() -endif() -if (${LLVM_FOUND}) - list(APPEND CMAKE_MODULE_PATH ${LLVM_CMAKE_DIR}) - include(AddLLVM) +set(BUILD_HIPIFY_CLANG 0 CACHE INTERNAL "") - message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}") +find_package(LLVM PATHS ${HIPIFY_CLANG_LLVM_DIR} REQUIRED) - include_directories(${LLVM_INCLUDE_DIRS}) - link_directories(${LLVM_LIBRARY_DIRS}) - add_definitions(${LLVM_DEFINITIONS}) - add_llvm_executable(hipify-clang src/Cuda2Hip.cpp) +list(APPEND CMAKE_MODULE_PATH ${LLVM_CMAKE_DIR}) +include(AddLLVM) - set(CMAKE_CXX_COMPILER ${LLVM_TOOLS_BINARY_DIR}/clang++) - set(CMAKE_C_COMPILER ${LLVM_TOOLS_BINARY_DIR}/clang) +message(STATUS "Found LLVM ${LLVM_PACKAGE_VERSION}") - # Link against LLVM and CLANG libraries - target_link_libraries(hipify-clang - clangASTMatchers - clangFrontend - clangTooling - clangParse - clangSerialization - clangSema - clangEdit - clangFormat - clangLex - clangAnalysis - clangDriver - clangAST - clangToolingCore - clangRewrite - clangBasic - LLVMProfileData - LLVMSupport - LLVMMCParser - LLVMMC - LLVMBitReader - LLVMOption - LLVMCore) +include_directories(${LLVM_INCLUDE_DIRS}) +link_directories(${LLVM_LIBRARY_DIRS}) +add_definitions(${LLVM_DEFINITIONS}) +add_llvm_executable(hipify-clang src/Cuda2Hip.cpp) + +set(CMAKE_CXX_COMPILER ${LLVM_TOOLS_BINARY_DIR}/clang++) +set(CMAKE_C_COMPILER ${LLVM_TOOLS_BINARY_DIR}/clang) + +# Link against LLVM and CLANG libraries +target_link_libraries(hipify-clang + clangASTMatchers + clangFrontend + clangTooling + clangParse + clangSerialization + clangSema + clangEdit + clangFormat + clangLex + clangAnalysis + clangDriver + clangAST + clangToolingCore + clangRewrite + clangBasic + LLVMProfileData + LLVMSupport + LLVMMCParser + LLVMMC + LLVMBitReader + LLVMOption + LLVMCore) if(WIN32) target_link_libraries(hipify-clang version) endif() - set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS}") +set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CFLAGS}") if(MSVC) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /GR- /EHs- /EHc-") set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} /SUBSYSTEM:WINDOWS") @@ -65,42 +65,31 @@ else() set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -pthread -fno-rtti -fvisibility-inlines-hidden") endif() - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DHIPIFY_CLANG_RES=\\\"${LLVM_LIBRARY_DIRS}/clang/${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH}\\\"") +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -DHIPIFY_CLANG_RES=\\\"${LLVM_LIBRARY_DIRS}/clang/${LLVM_VERSION_MAJOR}.${LLVM_VERSION_MINOR}.${LLVM_VERSION_PATCH}\\\"") - install(TARGETS hipify-clang DESTINATION bin) +install(TARGETS hipify-clang DESTINATION bin) if (HIPIFY_CLANG_TESTS) # tests - set(Python_ADDITIONAL_VERSIONS 2.7) - include(FindPythonInterp) - if(NOT PYTHONINTERP_FOUND) - message(FATAL_ERROR - "Unable to find Python interpreter, required for builds and testing.\n\n" - "Please install Python or specify the PYTHON_EXECUTABLE CMake variable.") - endif() - - find_program(LIT_COMMAND lit) + find_package(PythonInterp 2.7 REQUIRED EXACT) set(BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) configure_file( ${CMAKE_SOURCE_DIR}/tests/hipify-clang/lit.site.cfg.in ${CMAKE_CURRENT_BINARY_DIR}/tests/hipify-clang/lit.site.cfg - @ONLY) + @ONLY + ) add_lit_testsuite(test-hipify "Running HIPify regression tests" ${CMAKE_SOURCE_DIR}/tests/hipify-clang PARAMS site_config=${CMAKE_CURRENT_BINARY_DIR}/tests/hipify-clang/lit.site.cfg DEPENDS hipify-clang lit - ) + ) add_custom_target(test-hipify-clang) add_dependencies(test-hipify-clang test-hipify) set_target_properties(test-hipify-clang PROPERTIES FOLDER "Tests") endif() -if (PARENT_SCOPE) - set(BUILD_HIPIFY_CLANG 1 PARENT_SCOPE) -endif() - -endif() +set(BUILD_HIPIFY_CLANG 1 CACHE INTERNAL "") diff --git a/hipify-clang/src/Cuda2Hip.cpp b/hipify-clang/src/Cuda2Hip.cpp index 907e78e54f..0f73859893 100644 --- a/hipify-clang/src/Cuda2Hip.cpp +++ b/hipify-clang/src/Cuda2Hip.cpp @@ -2928,7 +2928,13 @@ protected: std::string mainFileName; virtual void insertReplacement(const Replacement &rep, const FullSourceLoc &fullSL) { +#if LLVM_VERSION_MAJOR > 3 + // New clang added error checking to Replacements, and *insists* that you explicitly check it. + llvm::Error e = Replace->add(rep); +#else + // In older versions, it's literally an std::set Replace->insert(rep); +#endif if (PrintStats) { LOCs.insert(fullSL.getExpansionLineNumber()); } @@ -3022,14 +3028,17 @@ class Cuda2HipCallback; class HipifyPPCallbacks : public PPCallbacks, public SourceFileCallbacks, public Cuda2Hip { public: HipifyPPCallbacks(Replacements *R, const std::string &mainFileName) - : Cuda2Hip(R, mainFileName), SeenEnd(false), _sm(nullptr), _pp(nullptr) {} + : Cuda2Hip(R, mainFileName) {} - virtual bool handleBeginSource(CompilerInstance &CI, StringRef Filename) override { + virtual bool handleBeginSource(CompilerInstance &CI +#if LLVM_VERSION_MAJOR < 4 + , StringRef Filename +#endif + ) override { Preprocessor &PP = CI.getPreprocessor(); SourceManager &SM = CI.getSourceManager(); setSourceManager(&SM); PP.addPPCallbacks(std::unique_ptr(this)); - PP.Retain(); setPreprocessor(&PP); return true; } @@ -3103,16 +3112,23 @@ public: const MacroDefinition &MD, SourceRange Range, const MacroArgs *Args) override { if (_sm->isWrittenInMainFile(MacroNameTok.getLocation())) { - for (unsigned int i = 0; Args && i < MD.getMacroInfo()->getNumArgs(); i++) { + // The getNumArgs function was rather unhelpfully renamed in clang 4.0. Its semantics + // remain unchanged. +#if LLVM_VERSION_MAJOR > 3 + #define GET_NUM_ARGS() getNumParams() +#else + #define GET_NUM_ARGS() getNumArgs() +#endif + for (unsigned int i = 0; Args && i < MD.getMacroInfo()->GET_NUM_ARGS(); i++) { std::vector toks; // Code below is a kind of stolen from 'MacroArgs::getPreExpArgument' // to workaround the 'const' MacroArgs passed into this hook. const Token *start = Args->getUnexpArgument(i); size_t len = Args->getArgLength(start) + 1; -#if (LLVM_VERSION_MAJOR >= 3) && (LLVM_VERSION_MINOR >= 9) - _pp->EnterTokenStream(ArrayRef(start, len), false); -#else +#if (LLVM_VERSION_MAJOR == 3) && (LLVM_VERSION_MINOR == 8) _pp->EnterTokenStream(start, len, false, false); +#else + _pp->EnterTokenStream(ArrayRef(start, len), false); #endif do { toks.push_back(Token()); @@ -3185,15 +3201,15 @@ public: void EndOfMainFile() override {} - bool SeenEnd; + bool SeenEnd = false; void setSourceManager(SourceManager *sm) { _sm = sm; } void setPreprocessor(Preprocessor *pp) { _pp = pp; } void setMatch(Cuda2HipCallback *match) { Match = match; } private: - SourceManager *_sm; - Preprocessor *_pp; - Cuda2HipCallback *Match; + SourceManager *_sm = nullptr; + Preprocessor *_pp = nullptr; + Cuda2HipCallback *Match = nullptr; }; class Cuda2HipCallback : public MatchFinder::MatchCallback, public Cuda2Hip { @@ -3799,7 +3815,7 @@ private: } bool stringLiteral(const MatchFinder::MatchResult &Result) { - if (const StringLiteral *sLiteral = Result.Nodes.getNodeAs("stringLiteral")) { + if (const clang::StringLiteral *sLiteral = Result.Nodes.getNodeAs("stringLiteral")) { if (sLiteral->getCharByteWidth() == 1) { StringRef s = sLiteral->getString(); SourceManager *SM = Result.SourceManager; @@ -4207,11 +4223,15 @@ void copyFile(const std::string& src, const std::string& dst) { int main(int argc, const char **argv) { auto start = std::chrono::steady_clock::now(); auto begin = start; -#if (LLVM_VERSION_MAJOR >= 3) && (LLVM_VERSION_MINOR >= 9) - llvm::sys::PrintStackTraceOnErrorSignal(StringRef()); -#else + + // The signature of PrintStackTraceOnErrorSignal changed in llvm 3.9. We don't support + // anything older than 3.8, so let's specifically detect the one old version we support. +#if (LLVM_VERSION_MAJOR == 3) && (LLVM_VERSION_MINOR == 8) llvm::sys::PrintStackTraceOnErrorSignal(); +#else + llvm::sys::PrintStackTraceOnErrorSignal(StringRef()); #endif + CommonOptionsParser OptionsParser(argc, argv, ToolTemplateCategory, llvm::cl::OneOrMore); std::vector fileSources = OptionsParser.getSourcePathList(); std::string dst = OutputFilename; @@ -4271,12 +4291,23 @@ int main(int argc, const char **argv) { // So what we do is operate on a copy, which we then move to the output. RefactoringTool Tool(OptionsParser.getCompilations(), tmpFile); ast_matchers::MatchFinder Finder; - HipifyPPCallbacks PPCallbacks(&Tool.getReplacements(), tmpFile); - Cuda2HipCallback Callback(&Tool.getReplacements(), &Finder, &PPCallbacks, tmpFile); + + // The Replacements to apply to the file `src`. + Replacements* replacementsToUse; +#if LLVM_VERSION_MAJOR > 3 + // getReplacements() now returns a map from filename to Replacements - so create an entry + // for this source file and return a pointer to it. + replacementsToUse = &(Tool.getReplacements()[tmpFile]); +#else + replacementsToUse = &Tool.getReplacements(); +#endif + + HipifyPPCallbacks* PPCallbacks = new HipifyPPCallbacks(replacementsToUse, tmpFile); + Cuda2HipCallback Callback(replacementsToUse, &Finder, PPCallbacks, tmpFile); addAllMatchers(Finder, &Callback); - auto action = newFrontendActionFactory(&Finder, &PPCallbacks); + auto action = newFrontendActionFactory(&Finder, PPCallbacks); Tool.appendArgumentsAdjuster(getInsertArgumentAdjuster("--cuda-host-only", ArgumentInsertPosition::BEGIN)); @@ -4300,9 +4331,14 @@ int main(int argc, const char **argv) { SourceManager SM(Diagnostics, Tool.getFiles()); if (PrintStats) { DEBUG(dbgs() << "Replacements collected by the tool:\n"); - for (const auto &r : Tool.getReplacements()) { - DEBUG(dbgs() << r.toString() << "\n"); - repBytes += r.getLength(); +#if LLVM_VERSION_MAJOR > 3 + Replacements& replacements = Tool.getReplacements().begin()->second; +#else + Replacements& replacements = Tool.getReplacements(); +#endif + for (const auto &replacement : replacements) { + DEBUG(dbgs() << replacement.toString() << "\n"); + repBytes += replacement.getLength(); } std::ifstream src_file(dst, std::ios::binary | std::ios::ate); src_file.clear(); @@ -4329,13 +4365,13 @@ int main(int argc, const char **argv) { } std::remove(csv.c_str()); } - if (0 == printStats(csv, src, PPCallbacks, Callback, repBytes, bytes, lines, start)) { + if (0 == printStats(csv, src, *PPCallbacks, Callback, repBytes, bytes, lines, start)) { filesTranslated--; } start = std::chrono::steady_clock::now(); repBytesTotal += repBytes; bytesTotal += bytes; - changedLinesTotal += PPCallbacks.LOCs.size() + Callback.LOCs.size(); + changedLinesTotal += PPCallbacks->LOCs.size() + Callback.LOCs.size(); linesTotal += lines; } dst.clear();