From 918504ecd6d5512ac89494510e2a462ac4c5a737 Mon Sep 17 00:00:00 2001 From: Larry Gritz Date: Tue, 17 Dec 2013 16:16:12 -0800 Subject: [PATCH 1/2] Clean up bitcode generation, including 3.4 fixes --- src/liboslexec/CMakeLists.txt | 64 +++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 26 deletions(-) diff --git a/src/liboslexec/CMakeLists.txt b/src/liboslexec/CMakeLists.txt index e3cadd335..ee945abd8 100644 --- a/src/liboslexec/CMakeLists.txt +++ b/src/liboslexec/CMakeLists.txt @@ -47,51 +47,63 @@ MACRO ( LLVM_COMPILE llvm_src srclist ) MESSAGE (STATUS "LLVM_COMPILE cpp=${llvm_bc_cpp}") endif () SET ( ${srclist} ${${srclist}} ${llvm_bc_cpp} ) - EXEC_PROGRAM ( "${LLVM_DIRECTORY}/bin/llvm-config" ARGS --cxxflags OUTPUT_VARIABLE LLVM_COMPILE_FLAGS ) - set (LLVM_COMPILE_FLAGS "${LLVM_COMPILE_FLAGS} -D__STDC_LIMIT_MACROS -D__STDC_CONSTANT_MACROS -O3 --combine") if (OSL_NAMESPACE) - LIST (APPEND LLVM_COMPILE_FLAGS "-DOSL_NAMESPACE=${OSL_NAMESPACE}") + SET (LLVM_COMPILE_FLAGS ${LLVM_COMPILE_FLAGS} "-DOSL_NAMESPACE=${OSL_NAMESPACE}") endif () if (OPENIMAGEIO_NAMESPACE) - LIST (APPEND LLVM_COMPILE_FLAGS "-DOPENIMAGEIO_NAMESPACE=${OPENIMAGEIO_NAMESPACE}") + SET (LLVM_COMPILE_FLAGS ${LLVM_COMPILE_FLAGS} "-DOPENIMAGEIO_NAMESPACE=${OPENIMAGEIO_NAMESPACE}") endif () get_property (CURRENT_DEFINITIONS DIRECTORY PROPERTY COMPILE_DEFINITIONS) if (VERBOSE) message (STATUS "Current #defines are ${CURRENT_DEFINITIONS}") endif () foreach (def ${CURRENT_DEFINITIONS}) - LIST (APPEND LLVM_COMPILE_FLAGS "-D${def}") + set (LLVM_COMPILE_FLAGS ${LLVM_COMPILE_FLAGS} "-D${def}") endforeach() - # First try looking in their build (clang++ first, then llvm-g++) - FIND_PROGRAM(LLVM_BC_GENERATOR NAMES "clang++" "llvm-g++" PATHS "${LLVM_DIRECTORY}/bin" NO_DEFAULT_PATH NO_CMAKE_SYSTEM_PATH NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_ENVIRONMENT_PATH NO_CMAKE_PATH) + # Figure out what program we will use to make the bitcode. + if (NOT LLVM_BC_GENERATOR) + FIND_PROGRAM(LLVM_BC_GENERATOR NAMES "clang++" PATHS "${LLVM_DIRECTORY}/bin" NO_DEFAULT_PATH NO_CMAKE_SYSTEM_PATH NO_SYSTEM_ENVIRONMENT_PATH NO_CMAKE_ENVIRONMENT_PATH NO_CMAKE_PATH) + endif () + # If that didn't work, look anywhere + if (NOT LLVM_BC_GENERATOR) + # Wasn't in their build, look anywhere + FIND_PROGRAM(LLVM_BC_GENERATOR NAMES clang++ llvm-g++) + endif () - if(NOT LLVM_BC_GENERATOR) - # Wasn't in their build, look anywhere - FIND_PROGRAM(LLVM_BC_GENERATOR NAMES clang++ llvm-g++) + if (NOT LLVM_BC_GENERATOR) + message (FATAL_ERROR "You must have a valid llvm bitcode generator (clang++) somewhere.") + endif () + if (VERBOSE) + message (STATUS "Using ${LLVM_BC_GENERATOR} to generate bitcode.") endif() - if(NOT LLVM_BC_GENERATOR) - message (FATAL_ERROR "You must have a valid llvm bitcode generator (either llvm-g++ or clang++) somewhere.") - else() - if (VERBOSE) - message (STATUS "Using ${LLVM_BC_GENERATOR} to generate bitcode.") - endif () - endif() + # Fix specific problem I had on new Apple systems (e.g. Mavericks) with + # LLVM/libc++ installed -- for some reason, LLVM 3.4 wasn't finding it, + # so in that specific case, append another -I to point it in the right + # direction. + if (APPLE AND ${LLVM_BC_GENERATOR} MATCHES ".*clang.*") + EXEC_PROGRAM ( "${LLVM_BC_GENERATOR}" ARGS --version OUTPUT_VARIABLE MY_CLANG_VERSION ) + string (REGEX REPLACE "clang version ([0-9][.][0-9]+).*" "\\1" MY_CLANG_VERSION "${MY_CLANG_VERSION}") + if ((${MY_CLANG_VERSION} VERSION_GREATER "3.3") + AND (EXISTS "/usr/lib/libc++.dylib") + AND (EXISTS "/Library/Developer/CommandLineTools/usr/lib/c++/v1")) + set (LLVM_COMPILE_FLAGS ${LLVM_COMPILE_FLAGS} "-I/Library/Developer/CommandLineTools/usr/lib/c++/v1") + endif () + endif () # Command to turn the .cpp file into LLVM assembly language .s, into # LLVM bitcode .bc, then back into a C++ file with the bc embedded! ADD_CUSTOM_COMMAND ( OUTPUT ${llvm_bc_cpp} COMMAND ${LLVM_BC_GENERATOR} - "-I${CMAKE_CURRENT_SOURCE_DIR}" - "-I${CMAKE_SOURCE_DIR}/src/include" - "-I${CMAKE_BINARY_DIR}/include" - "-I${OPENIMAGEIO_INCLUDES}" - "-I${ILMBASE_INCLUDE_DIR}" - "-I${Boost_INCLUDE_DIRS}" - ${LLVM_COMPILE_FLAGS} - -O3 -S -emit-llvm -o ${llvm_asm} ${llvm_src} - + ${LLVM_COMPILE_FLAGS} + "-I${CMAKE_CURRENT_SOURCE_DIR}" + "-I${CMAKE_SOURCE_DIR}/src/include" + "-I${CMAKE_BINARY_DIR}/include" + "-I${OPENIMAGEIO_INCLUDES}" + "-I${ILMBASE_INCLUDE_DIR}" + "-I${Boost_INCLUDE_DIRS}" + -O3 -S -emit-llvm -o ${llvm_asm} ${llvm_src} COMMAND "${LLVM_DIRECTORY}/bin/llvm-as" -f -o ${llvm_bc} ${llvm_asm} COMMAND "${CMAKE_CURRENT_SOURCE_DIR}/serialize-bc.bash" ${llvm_bc} ${llvm_bc_cpp} MAIN_DEPENDENCY ${llvm_src} From 6a572ac92ed61b9075dd8bc951b02b6d103b3031 Mon Sep 17 00:00:00 2001 From: Larry Gritz Date: Fri, 3 Jan 2014 15:36:00 -0800 Subject: [PATCH 2/2] Make OSL work with LLVM 3.4 --- src/cmake/externalpackages.cmake | 4 +- src/include/llvm_util.h | 18 +++- src/liboslexec/llvm_util.cpp | 139 +++++++++++++++++++++++-------- 3 files changed, 121 insertions(+), 40 deletions(-) diff --git a/src/cmake/externalpackages.cmake b/src/cmake/externalpackages.cmake index a0206c914..4b19de5ff 100644 --- a/src/cmake/externalpackages.cmake +++ b/src/cmake/externalpackages.cmake @@ -173,9 +173,9 @@ endif() find_library ( LLVM_LIBRARY NAMES LLVM-${LLVM_VERSION} PATHS ${LLVM_LIB_DIR}) +message (STATUS "LLVM version = ${LLVM_VERSION}") +message (STATUS "LLVM dir = ${LLVM_DIRECTORY}") if (VERBOSE) - message (STATUS "LLVM version = ${LLVM_VERSION}") - message (STATUS "LLVM dir = ${LLVM_DIRECTORY}") message (STATUS "LLVM includes = ${LLVM_INCLUDES}") message (STATUS "LLVM library = ${LLVM_LIBRARY}") message (STATUS "LLVM lib dir = ${LLVM_LIB_DIR}") diff --git a/src/include/llvm_util.h b/src/include/llvm_util.h index c13163d1b..d4a9fad60 100644 --- a/src/include/llvm_util.h +++ b/src/include/llvm_util.h @@ -42,18 +42,25 @@ namespace llvm { class ConstantFolder; class ExecutionEngine; class Function; - class FunctionPassManager; class FunctionType; class JITMemoryManager; class Linker; class LLVMContext; class Module; - class PassManager; class PointerType; class Type; class Value; template class IRBuilder; template class IRBuilderDefaultInserter; +#if OSL_LLVM_VERSION >= 34 + namespace legacy { + class FunctionPassManager; + class PassManager; + } +#else + class FunctionPassManager; + class PassManager; +#endif } @@ -473,8 +480,13 @@ class OSLEXECPUBLIC LLVM_Util { IRBuilder *m_builder; OSL_Dummy_JITMemoryManager *m_llvm_jitmm; llvm::Function *m_current_function; - llvm::PassManager *m_llvm_passes; +#if OSL_LLVM_VERSION >= 34 + llvm::legacy::PassManager *m_llvm_module_passes; + llvm::legacy::FunctionPassManager *m_llvm_func_passes; +#else + llvm::PassManager *m_llvm_module_passes; llvm::FunctionPassManager *m_llvm_func_passes; +#endif llvm::ExecutionEngine *m_llvm_exec; std::vector m_return_block; // stack for func call std::vector m_loop_after_block; // stack for break diff --git a/src/liboslexec/llvm_util.cpp b/src/liboslexec/llvm_util.cpp index df8f35ed4..d9fa3adf9 100644 --- a/src/liboslexec/llvm_util.cpp +++ b/src/liboslexec/llvm_util.cpp @@ -44,6 +44,11 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # include # include # include +# if OSL_LLVM_VERSION >= 34 +# include +# else +# include +# endif #else /* older releases */ @@ -61,13 +66,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. # include # include # endif +# include #endif #include #include #include -#include #include #include #include @@ -175,6 +180,7 @@ class OSL_Dummy_JITMemoryManager : public llvm::JITMemoryManager { virtual void deallocateFunctionBody(void *Body) { // DON'T DEALLOCATE mm->deallocateFunctionBody (Body); } +#if OSL_LLVM_VERSION <= 33 virtual uint8_t* startExceptionTable(const llvm::Function* F, uintptr_t &ActualSize) { return mm->startExceptionTable (F, ActualSize); @@ -186,6 +192,7 @@ class OSL_Dummy_JITMemoryManager : public llvm::JITMemoryManager { virtual void deallocateExceptionTable(void *ET) { // DON'T DEALLOCATE mm->deallocateExceptionTable(ET); } +#endif virtual bool CheckInvariants(std::string &s) { return mm->CheckInvariants(s); } @@ -201,7 +208,41 @@ class OSL_Dummy_JITMemoryManager : public llvm::JITMemoryManager { virtual unsigned GetNumCodeSlabs() { return mm->GetNumCodeSlabs(); } virtual unsigned GetNumDataSlabs() { return mm->GetNumDataSlabs(); } virtual unsigned GetNumStubSlabs() { return mm->GetNumStubSlabs(); } -#if OSL_LLVM_VERSION >= 31 + +#if OSL_LLVM_VERSION >= 34 + + virtual void *getPointerToNamedFunction(const std::string &Name, + bool AbortOnFailure = true) { + return mm->getPointerToNamedFunction (Name, AbortOnFailure); + } + virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, + unsigned SectionID, llvm::StringRef SectionName) { + return mm->allocateCodeSection(Size, Alignment, SectionID, SectionName); + } + virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, + unsigned SectionID, llvm::StringRef SectionName, + bool IsReadOnly) { + return mm->allocateDataSection(Size, Alignment, SectionID, + SectionName, IsReadOnly); + } + virtual void registerEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) { + mm->registerEHFrames (Addr, LoadAddr, Size); + } + virtual void deregisterEHFrames(uint8_t *Addr, uint64_t LoadAddr, size_t Size) { + mm->deregisterEHFrames(Addr, LoadAddr, Size); + } + virtual uint64_t getSymbolAddress(const std::string &Name) { + return mm->getSymbolAddress (Name); + } + virtual void notifyObjectLoaded(llvm::ExecutionEngine *EE, const llvm::ObjectImage *oi) { + mm->notifyObjectLoaded (EE, oi); + } + virtual bool finalizeMemory(std::string *ErrMsg = 0) { + return mm->finalizeMemory (ErrMsg); + } + +#elif OSL_LLVM_VERSION == 33 + virtual void *getPointerToNamedFunction(const std::string &Name, bool AbortOnFailure = true) { return mm->getPointerToNamedFunction (Name, AbortOnFailure); @@ -210,7 +251,6 @@ class OSL_Dummy_JITMemoryManager : public llvm::JITMemoryManager { unsigned SectionID) { return mm->allocateCodeSection(Size, Alignment, SectionID); } -#if OSL_LLVM_VERSION >= 33 virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID, bool IsReadOnly) { return mm->allocateDataSection(Size, Alignment, SectionID, IsReadOnly); @@ -218,12 +258,22 @@ class OSL_Dummy_JITMemoryManager : public llvm::JITMemoryManager { virtual bool applyPermissions(std::string *ErrMsg = 0) { return mm->applyPermissions(ErrMsg); } -#else + +#elif OSL_LLVM_VERSION == 32 || OSL_LLVM_VERSION == 31 + + virtual void *getPointerToNamedFunction(const std::string &Name, + bool AbortOnFailure = true) { + return mm->getPointerToNamedFunction (Name, AbortOnFailure); + } + virtual uint8_t *allocateCodeSection(uintptr_t Size, unsigned Alignment, + unsigned SectionID) { + return mm->allocateCodeSection(Size, Alignment, SectionID); + } virtual uint8_t *allocateDataSection(uintptr_t Size, unsigned Alignment, unsigned SectionID) { return mm->allocateDataSection(Size, Alignment, SectionID); } -#endif + #endif }; @@ -234,7 +284,7 @@ LLVM_Util::LLVM_Util () : m_thread(NULL), m_llvm_context(NULL), m_llvm_module(NULL), m_builder(NULL), m_llvm_jitmm(NULL), m_current_function(NULL), - m_llvm_passes(NULL), m_llvm_func_passes(NULL), + m_llvm_module_passes(NULL), m_llvm_func_passes(NULL), m_llvm_exec(NULL) { SetupLLVM (); @@ -289,7 +339,7 @@ LLVM_Util::LLVM_Util () LLVM_Util::~LLVM_Util () { execengine (NULL); - delete m_llvm_passes; + delete m_llvm_module_passes; delete m_llvm_func_passes; delete m_builder; module (NULL); @@ -306,8 +356,12 @@ LLVM_Util::SetupLLVM () return; // Some global LLVM initialization for the first thread that // gets here. - // info ("Setting up LLVM"); + +#if OSL_LLVM_VERSION <= 33 + // Starting with LLVM 3.4, the pretty stack trace was opt-in rather + // than opt-out, and the following variable was removed. llvm::DisablePrettyStackTrace = true; +#endif llvm::llvm_start_multithreaded (); // enable it to be thread-safe llvm::InitializeNativeTarget(); setup_done = true; @@ -408,29 +462,42 @@ LLVM_Util::getPointerToFunction (llvm::Function *func) void LLVM_Util::setup_optimization_passes (int optlevel) { - ASSERT (m_llvm_passes == NULL && m_llvm_func_passes == NULL); + ASSERT (m_llvm_module_passes == NULL && m_llvm_func_passes == NULL); // Specify per-function passes // +#if OSL_LLVM_VERSION >= 34 + m_llvm_func_passes = new llvm::legacy::FunctionPassManager(module()); + llvm::legacy::FunctionPassManager &fpm (*m_llvm_func_passes); + fpm.add (new llvm::DataLayout(module())); +#else m_llvm_func_passes = new llvm::FunctionPassManager(module()); llvm::FunctionPassManager &fpm (*m_llvm_func_passes); -#if OSL_LLVM_VERSION >= 32 +# if OSL_LLVM_VERSION >= 32 fpm.add (new llvm::DataLayout(module())); -#else +# else fpm.add (new llvm::TargetData(module())); +# endif #endif // Specify module-wide (interprocedural optimization) passes // - m_llvm_passes = new llvm::PassManager; - llvm::PassManager &passes (*m_llvm_passes); +#if OSL_LLVM_VERSION >= 34 + m_llvm_module_passes = new llvm::legacy::PassManager; + llvm::legacy::PassManager &mpm (*m_llvm_module_passes); + mpm.add (new llvm::DataLayout(module())); +#else + m_llvm_module_passes = new llvm::PassManager; + llvm::PassManager &mpm (*m_llvm_module_passes); #if OSL_LLVM_VERSION >= 32 - passes.add (new llvm::DataLayout(module())); + mpm.add (new llvm::DataLayout(module())); #else - passes.add (new llvm::TargetData(module())); + mpm.add (new llvm::TargetData(module())); +#endif #endif if (optlevel >= 1 && optlevel <= 3) { +#if OSL_LLVM_VERSION <= 34 // For LLVM 3.0 and higher, llvm_optimize 1-3 means to use the // same set of optimizations as clang -O1, -O2, -O3 llvm::PassManagerBuilder builder; @@ -438,42 +505,40 @@ LLVM_Util::setup_optimization_passes (int optlevel) builder.Inliner = llvm::createFunctionInliningPass(); // builder.DisableUnrollLoops = true; builder.populateFunctionPassManager (fpm); - builder.populateModulePassManager (passes); - // Skip this for now, investigate later. FIXME. - // builder.populateLTOPassManager (passes, true /* internalize */, - // true /* inline once again */); - builder.populateModulePassManager (passes); + builder.populateModulePassManager (mpm); +#endif + } else { // LLVM 2.x, or unknown choices for llvm_optimize: use the same basic // set of passes that we always have. // Always add verifier? - passes.add (llvm::createVerifierPass()); + mpm.add (llvm::createVerifierPass()); // Simplify the call graph if possible (deleting unreachable blocks, etc.) - passes.add (llvm::createCFGSimplificationPass()); + mpm.add (llvm::createCFGSimplificationPass()); // Change memory references to registers - // passes.add (llvm::createPromoteMemoryToRegisterPass()); - passes.add (llvm::createScalarReplAggregatesPass()); + // mpm.add (llvm::createPromoteMemoryToRegisterPass()); + mpm.add (llvm::createScalarReplAggregatesPass()); // Combine instructions where possible -- peephole opts & bit-twiddling - passes.add (llvm::createInstructionCombiningPass()); + mpm.add (llvm::createInstructionCombiningPass()); // Inline small functions - passes.add (llvm::createFunctionInliningPass()); // 250? + mpm.add (llvm::createFunctionInliningPass()); // 250? // Eliminate early returns - passes.add (llvm::createUnifyFunctionExitNodesPass()); + mpm.add (llvm::createUnifyFunctionExitNodesPass()); // resassociate exprssions (a = x + (3 + y) -> a = x + y + 3) - passes.add (llvm::createReassociatePass()); + mpm.add (llvm::createReassociatePass()); // Eliminate common sub-expressions - passes.add (llvm::createGVNPass()); + mpm.add (llvm::createGVNPass()); // Constant propagation with SCCP - passes.add (llvm::createSCCPPass()); + mpm.add (llvm::createSCCPPass()); // More dead code elimination - passes.add (llvm::createAggressiveDCEPass()); + mpm.add (llvm::createAggressiveDCEPass()); // Combine instructions where possible -- peephole opts & bit-twiddling - passes.add (llvm::createInstructionCombiningPass()); + mpm.add (llvm::createInstructionCombiningPass()); // Simplify the call graph if possible (deleting unreachable blocks, etc.) - passes.add (llvm::createCFGSimplificationPass()); + mpm.add (llvm::createCFGSimplificationPass()); // Try to make stuff into registers one last time. - passes.add (llvm::createPromoteMemoryToRegisterPass()); + mpm.add (llvm::createPromoteMemoryToRegisterPass()); } } @@ -482,7 +547,11 @@ LLVM_Util::setup_optimization_passes (int optlevel) void LLVM_Util::do_optimize () { - m_llvm_passes->run (*module()); +#if OSL_LLVM_VERSION >= 34 + m_llvm_module_passes->run (*module()); +#else + m_llvm_module_passes->run (*module()); +#endif }