From 1ac5e84e9179fd9c02b5f8d6c46eaab58baa6e4b Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 26 Feb 2014 14:06:27 -0800 Subject: [PATCH 1/2] rustc: Get rustc compiling with LLVM 3.{3,4} again The travis builds have been breaking recently because LLVM 3.5 upstream is changing. This looks like it's likely to continue, so it would be more useful for us if we could lock ourselves to a system LLVM version that is not changing. This commit has the support to bring our C++ glue to LLVM back in line with what was possible back in LLVM 3.{3,4}. I don't think we're going to be able to reasonably protect against regressions in the future, but this kind of code is a good sign that we can continue to use the system LLVM for simple-ish things. Codegen for ARM won't work and it won't have some of the perf improvements we have, but using the system LLVM should work well enough for development. --- src/rustllvm/PassWrapper.cpp | 16 +++++++++ src/rustllvm/RustWrapper.cpp | 63 ++++++++++++++++++++++++++++++++---- src/rustllvm/rustllvm.h | 7 +++- 3 files changed, 78 insertions(+), 8 deletions(-) diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index c1655b3a41500..2be7c84ab0348 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -166,7 +166,11 @@ LLVMRustWriteOutputFile(LLVMTargetMachineRef Target, PassManager *PM = unwrap(PMR); std::string ErrorInfo; +#if LLVM_VERSION_MINOR >= 4 raw_fd_ostream OS(path, ErrorInfo, sys::fs::F_None); +#else + raw_fd_ostream OS(path, ErrorInfo, raw_fd_ostream::F_Binary); +#endif if (ErrorInfo != "") { LLVMRustError = ErrorInfo.c_str(); return false; @@ -184,9 +188,21 @@ LLVMRustPrintModule(LLVMPassManagerRef PMR, const char* path) { PassManager *PM = unwrap(PMR); std::string ErrorInfo; + +#if LLVM_VERSION_MINOR >= 4 raw_fd_ostream OS(path, ErrorInfo, sys::fs::F_None); +#else + raw_fd_ostream OS(path, ErrorInfo, raw_fd_ostream::F_Binary); +#endif + formatted_raw_ostream FOS(OS); + +#if LLVM_VERSION_MINOR >= 5 PM->add(createPrintModulePass(FOS)); +#else + PM->add(createPrintModulePass(&FOS)); +#endif + PM->run(*unwrap(M)); } diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 75e0375b13ecb..d8fc5b15850e1 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -91,10 +91,14 @@ extern "C" void LLVMRemoveReturnAttribute(LLVMValueRef Fn, LLVMAttribute PA) { AttributeSet::get(A->getContext(), AttributeSet::ReturnIndex, B)); } +#if LLVM_VERSION_MINOR >= 5 extern "C" void LLVMAddColdAttribute(LLVMValueRef Fn) { Function *A = unwrap(Fn); A->addAttribute(AttributeSet::FunctionIndex, Attribute::Cold); } +#else +extern "C" void LLVMAddColdAttribute(LLVMValueRef Fn) {} +#endif extern "C" LLVMValueRef LLVMBuildAtomicLoad(LLVMBuilderRef B, LLVMValueRef source, @@ -156,7 +160,11 @@ DIT unwrapDI(LLVMValueRef ref) { return DIT(ref ? unwrap(ref) : NULL); } +#if LLVM_VERSION_MINOR >= 5 extern "C" const uint32_t LLVMRustDebugMetadataVersion = DEBUG_METADATA_VERSION; +#else +extern "C" const uint32_t LLVMRustDebugMetadataVersion = 1; +#endif extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M, const char *name, @@ -278,8 +286,12 @@ extern "C" LLVMValueRef LLVMDIBuilderCreateStructType( unwrapDI(DerivedFrom), unwrapDI(Elements), RunTimeLang, - unwrapDI(VTableHolder), - UniqueId)); + unwrapDI(VTableHolder) +#if LLVM_VERSION_MINOR >= 5 + ,UniqueId)); +#else + )); +#endif } extern "C" LLVMValueRef LLVMDIBuilderCreateMemberType( @@ -440,8 +452,12 @@ extern "C" LLVMValueRef LLVMDIBuilderCreateUnionType( AlignInBits, Flags, unwrapDI(Elements), - RunTimeLang, - UniqueId)); + RunTimeLang +#if LLVM_VERSION_MINOR >= 5 + ,UniqueId)); +#else + )); +#endif } extern "C" void LLVMSetUnnamedAddr(LLVMValueRef Value, LLVMBool Unnamed) { @@ -541,6 +557,7 @@ extern "C" char *LLVMValueToString(LLVMValueRef Value) { return strdup(os.str().data()); } +#if LLVM_VERSION_MINOR >= 5 extern "C" bool LLVMRustLinkInExternalBitcode(LLVMModuleRef dst, char *bc, size_t len) { Module *Dst = unwrap(dst); @@ -559,6 +576,26 @@ LLVMRustLinkInExternalBitcode(LLVMModuleRef dst, char *bc, size_t len) { } return true; } +#else +extern "C" bool +LLVMRustLinkInExternalBitcode(LLVMModuleRef dst, char *bc, size_t len) { + Module *Dst = unwrap(dst); + MemoryBuffer* buf = MemoryBuffer::getMemBufferCopy(StringRef(bc, len)); + std::string Err; + Module *Src = llvm::getLazyBitcodeModule(buf, Dst->getContext(), &Err); + if (!Src) { + LLVMRustError = Err.c_str(); + delete buf; + return false; + } + + if (Linker::LinkModules(Dst, Src, Linker::DestroySource, &Err)) { + LLVMRustError = Err.c_str(); + return false; + } + return true; +} +#endif extern "C" void* LLVMRustOpenArchive(char *path) { @@ -578,9 +615,14 @@ LLVMRustOpenArchive(char *path) { extern "C" const char* LLVMRustArchiveReadSection(Archive *ar, char *name, size_t *size) { - for (Archive::child_iterator child = ar->child_begin(), - end = ar->child_end(); - child != end; ++child) { +#if LLVM_VERSION_MINOR >= 5 + Archive::child_iterator child = ar->child_begin(), + end = ar->child_end(); +#else + Archive::child_iterator child = ar->begin_children(), + end = ar->end_children(); +#endif + for (; child != end; ++child) { StringRef sect_name; error_code err = child->getName(sect_name); if (err) continue; @@ -598,8 +640,15 @@ LLVMRustDestroyArchive(Archive *ar) { delete ar; } +#if LLVM_VERSION_MINOR >= 5 extern "C" void LLVMRustSetDLLExportStorageClass(LLVMValueRef Value) { GlobalValue *V = unwrap(Value); V->setDLLStorageClass(GlobalValue::DLLExportStorageClass); } +#else +extern "C" void +LLVMRustSetDLLExportStorageClass(LLVMValueRef Value) { + LLVMSetLinkage(Value, LLVMDLLExportLinkage); +} +#endif diff --git a/src/rustllvm/rustllvm.h b/src/rustllvm/rustllvm.h index e45a910fc8cab..f046587052a12 100644 --- a/src/rustllvm/rustllvm.h +++ b/src/rustllvm/rustllvm.h @@ -16,7 +16,6 @@ #include "llvm/PassManager.h" #include "llvm/IR/InlineAsm.h" #include "llvm/IR/LLVMContext.h" -#include "llvm/IR/IRPrintingPasses.h" #include "llvm/Analysis/Passes.h" #include "llvm/Analysis/Lint.h" #include "llvm/ADT/ArrayRef.h" @@ -52,6 +51,12 @@ #include "llvm-c/ExecutionEngine.h" #include "llvm-c/Object.h" +#if LLVM_VERSION_MINOR >= 5 +#include "llvm/IR/IRPrintingPasses.h" +#else +#include "llvm/Assembly/PrintModulePass.h" +#endif + // Used by RustMCJITMemoryManager::getPointerToNamedFunction() // to get around glibc issues. See the function for more information. #ifdef __linux__ From bbdaf01a5aa3ef55b693384465e61db1007a9a09 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Wed, 26 Feb 2014 15:04:18 -0800 Subject: [PATCH 2/2] travis: Use LLVM 3.3 from the official repos We can be certain that this version of LLVM will not be changing, so we don't have to worry about API drift over time. --- .travis.yml | 27 +++++++++------------------ 1 file changed, 9 insertions(+), 18 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2c2ef693d0b3d..310d3f4111fd3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,32 +3,23 @@ # it treats unknown languages as ruby-like I believe. language: c -# Before we start doing anything, install the latest stock LLVM. These are -# maintained by LLVM, and more information can be found at llvm.org/apt. -# -# Right now, the highest version is 3.5, and our SVN version is roughly aligned -# with the 3.5 API (hurray!) +# Before we start doing anything, install a stock LLVM install: - - sudo sh -c "echo 'deb http://llvm.org/apt/precise/ llvm-toolchain-precise main' >> /etc/apt/sources.list" - - sudo sh -c "echo 'deb-src http://llvm.org/apt/precise/ llvm-toolchain-precise main' >> /etc/apt/sources.list" - - sudo sh -c "echo 'deb http://ppa.launchpad.net/ubuntu-toolchain-r/test/ubuntu precise main' >> /etc/apt/sources.list" - - wget -O - http://llvm.org/apt/llvm-snapshot.gpg.key | sudo apt-key add - - - sudo apt-get update -qq - - sudo apt-get install -y --force-yes -qq llvm-3.5 llvm-3.5-dev clang-3.5 lldb-3.5 + - sudo apt-get install llvm-3.3 llvm-3.3-dev clang-3.3 lldb-3.3 -# All of the llvm tools are suffixed with "-3.5" which we don't want, so symlink +# All of the llvm tools are suffixed with "-3.3" which we don't want, so symlink # them all into a local directory and just use that # # FIXME: this shouldn't update the src/llvm sub-repo, that takes about a minute # it's gotta download so much stuff. before_script: - mkdir -p local-llvm/bin - - ln -nsf /usr/bin/llvm-config-3.5 local-llvm/bin/llvm-config - - ln -nsf /usr/bin/llvm-mc-3.5 local-llvm/bin/llvm-mc - - ln -nsf /usr/bin/llvm-as-3.5 local-llvm/bin/llvm-as - - ln -nsf /usr/bin/llvm-dis-3.5 local-llvm/bin/llvm-dis - - ln -nsf /usr/bin/llc-3.5 local-llvm/bin/llc - - ln -nsf /usr/include/llvm-3.5 local-llvm/include + - ln -nsf /usr/bin/llvm-config-3.3 local-llvm/bin/llvm-config + - ln -nsf /usr/bin/llvm-mc-3.3 local-llvm/bin/llvm-mc + - ln -nsf /usr/bin/llvm-as-3.3 local-llvm/bin/llvm-as + - ln -nsf /usr/bin/llvm-dis-3.3 local-llvm/bin/llvm-dis + - ln -nsf /usr/bin/llc-3.3 local-llvm/bin/llc + - ln -nsf /usr/include/llvm-3.3 local-llvm/include - ./configure --disable-optimize-tests --llvm-root=`pwd`/local-llvm --enable-fast-make --enable-clang # Tidy everything up first, then build a few things, and then run a few tests.