From 30ff17f809869dec37d7b501fb532dc88fd47832 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 31 Mar 2014 14:43:19 -0700 Subject: [PATCH] Upgrade LLVM This comes with a number of fixes to be compatible with upstream LLVM: * Previously all monomorphizations of "mem::size_of()" would receive the same symbol. In the past LLVM would silently rename duplicated symbols, but it appears to now be dropping the duplicate symbols and functions now. The symbol names of monomorphized functions are now no longer solely based on the type of the function, but rather the type and the unique hash for the monomorphization. * Split stacks are no longer a global feature controlled by a flag in LLVM. Instead, they are opt-in on a per-function basis through a function attribute. The rust #[no_split_stack] attribute will disable this, otherwise all functions have #[split_stack] attached to them. * The compare and swap instruction now takes two atomic orderings, one for the successful case and one for the failure case. LLVM internally has an implementation of calculating the appropriate failure ordering given a particular success ordering (previously only a success ordering was specified), and I copied that into the intrinsic translation so the failure ordering isn't supplied on a source level for now. * Minor tweaks to LLVM's API in terms of debuginfo, naming, c++11 conventions, etc. --- configure | 4 -- src/librustc/lib/llvm.rs | 6 ++- src/librustc/middle/trans/base.rs | 8 ++-- src/librustc/middle/trans/build.rs | 5 ++- src/librustc/middle/trans/builder.rs | 6 ++- src/librustc/middle/trans/debuginfo.rs | 6 ++- src/librustc/middle/trans/intrinsic.rs | 15 ++++++- src/librustc/middle/trans/monomorphize.rs | 7 ++-- src/llvm | 2 +- src/rustllvm/PassWrapper.cpp | 6 +++ src/rustllvm/RustWrapper.cpp | 48 ++++++++++++++++++----- src/rustllvm/llvm-auto-clean-trigger | 2 +- src/rustllvm/rustllvm.h | 9 +++-- 13 files changed, 89 insertions(+), 35 deletions(-) diff --git a/configure b/configure index 3fe0f376feb..8099aada558 100755 --- a/configure +++ b/configure @@ -921,10 +921,6 @@ do LLVM_OPTS="$LLVM_OPTS --disable-terminfo" # Try to have LLVM pull in as few dependencies as possible (#9397) LLVM_OPTS="$LLVM_OPTS --disable-zlib --disable-libffi" - # LLVM says it needs a "new" clang/gcc, but we seem to get by ok with - # older versions on the bots. Get by for a little longer by asking it to - # not do version detection - LLVM_OPTS="$LLVM_OPTS --disable-compiler-version-checks" # Use win32 native thread/lock apis instead of pthread wrapper. # (llvm's configure tries to find pthread first, so we have to disable it explicitly.) diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index 62c14e560e7..10e717e550d 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -1261,7 +1261,8 @@ pub mod llvm { LHS: ValueRef, CMP: ValueRef, RHS: ValueRef, - Order: AtomicOrdering) + Order: AtomicOrdering, + FailureOrder: AtomicOrdering) -> ValueRef; pub fn LLVMBuildAtomicRMW(B: BuilderRef, Op: AtomicBinOp, @@ -1586,7 +1587,8 @@ pub mod llvm { Scope: DIDescriptor, File: DIFile, Line: c_uint, - Col: c_uint) + Col: c_uint, + Discriminator: c_uint) -> DILexicalBlock; pub fn LLVMDIBuilderCreateStaticVariable(Builder: DIBuilderRef, diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 5f063bb31ca..95b928587c4 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -445,8 +445,8 @@ pub fn set_llvm_fn_attrs(attrs: &[ast::Attribute], llfn: ValueRef) { } // Add the no-split-stack attribute if requested - if contains_name(attrs, "no_split_stack") { - set_no_split_stack(llfn); + if !contains_name(attrs, "no_split_stack") { + set_split_stack(llfn); } if contains_name(attrs, "cold") { @@ -458,8 +458,8 @@ pub fn set_always_inline(f: ValueRef) { lib::llvm::SetFunctionAttribute(f, lib::llvm::AlwaysInlineAttribute) } -pub fn set_no_split_stack(f: ValueRef) { - "no-split-stack".with_c_str(|buf| { +pub fn set_split_stack(f: ValueRef) { + "split-stack".with_c_str(|buf| { unsafe { llvm::LLVMAddFunctionAttrString(f, buf); } }) } diff --git a/src/librustc/middle/trans/build.rs b/src/librustc/middle/trans/build.rs index c60a1e219d0..65db4bdc9ab 100644 --- a/src/librustc/middle/trans/build.rs +++ b/src/librustc/middle/trans/build.rs @@ -814,8 +814,9 @@ pub fn Resume(cx: &Block, exn: ValueRef) -> ValueRef { // Atomic Operations pub fn AtomicCmpXchg(cx: &Block, dst: ValueRef, cmp: ValueRef, src: ValueRef, - order: AtomicOrdering) -> ValueRef { - B(cx).atomic_cmpxchg(dst, cmp, src, order) + order: AtomicOrdering, + failure_order: AtomicOrdering) -> ValueRef { + B(cx).atomic_cmpxchg(dst, cmp, src, order, failure_order) } pub fn AtomicRMW(cx: &Block, op: AtomicBinOp, dst: ValueRef, src: ValueRef, diff --git a/src/librustc/middle/trans/builder.rs b/src/librustc/middle/trans/builder.rs index 7d99ac3e7f3..a02453a2554 100644 --- a/src/librustc/middle/trans/builder.rs +++ b/src/librustc/middle/trans/builder.rs @@ -949,9 +949,11 @@ impl<'a> Builder<'a> { // Atomic Operations pub fn atomic_cmpxchg(&self, dst: ValueRef, cmp: ValueRef, src: ValueRef, - order: AtomicOrdering) -> ValueRef { + order: AtomicOrdering, + failure_order: AtomicOrdering) -> ValueRef { unsafe { - llvm::LLVMBuildAtomicCmpXchg(self.llbuilder, dst, cmp, src, order) + llvm::LLVMBuildAtomicCmpXchg(self.llbuilder, dst, cmp, src, + order, failure_order) } } pub fn atomic_rmw(&self, op: AtomicBinOp, diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index 0514642c583..fd6a465eabb 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -2422,7 +2422,8 @@ fn populate_scope_map(cx: &CrateContext, parent_scope, file_metadata, loc.line as c_uint, - loc.col.to_uint() as c_uint) + loc.col.to_uint() as c_uint, + 0) }; scope_stack.push(ScopeStackEntry { scope_metadata: scope_metadata, ident: None }); @@ -2539,7 +2540,8 @@ fn populate_scope_map(cx: &CrateContext, parent_scope, file_metadata, loc.line as c_uint, - loc.col.to_uint() as c_uint) + loc.col.to_uint() as c_uint, + 0) }; scope_stack.push(ScopeStackEntry { diff --git a/src/librustc/middle/trans/intrinsic.rs b/src/librustc/middle/trans/intrinsic.rs index 6f4b115ad86..9e5213e6a99 100644 --- a/src/librustc/middle/trans/intrinsic.rs +++ b/src/librustc/middle/trans/intrinsic.rs @@ -223,10 +223,23 @@ pub fn trans_intrinsic(ccx: &CrateContext, match *split.get(1) { "cxchg" => { + // See include/llvm/IR/Instructions.h for their implementation + // of this, I assume that it's good enough for us to use for + // now. + let strongest_failure_ordering = match order { + lib::llvm::NotAtomic | lib::llvm::Unordered => + ccx.sess().fatal("cmpxchg must be atomic"), + lib::llvm::Monotonic | lib::llvm::Release => + lib::llvm::Monotonic, + lib::llvm::Acquire | lib::llvm::AcquireRelease => + lib::llvm::Acquire, + lib::llvm::SequentiallyConsistent => + lib::llvm::SequentiallyConsistent, + }; let old = AtomicCmpXchg(bcx, get_param(decl, first_real_arg), get_param(decl, first_real_arg + 1u), get_param(decl, first_real_arg + 2u), - order); + order, strongest_failure_ordering); Ret(bcx, old); } "load" => { diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs index 6f2dbc182b0..35ae9a26954 100644 --- a/src/librustc/middle/trans/monomorphize.rs +++ b/src/librustc/middle/trans/monomorphize.rs @@ -8,8 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. - -use back::link::mangle_exported_name; +use back::link::exported_name; use driver::session; use lib::llvm::ValueRef; use middle::trans::base::{set_llvm_fn_attrs, set_inline_hint}; @@ -27,6 +26,7 @@ use syntax::abi; use syntax::ast; use syntax::ast_map; use syntax::ast_util::local_def; +use std::hash::sip; pub fn monomorphic_fn(ccx: &CrateContext, fn_id: ast::DefId, @@ -178,7 +178,8 @@ pub fn monomorphic_fn(ccx: &CrateContext, } let s = ccx.tcx.map.with_path(fn_id.node, |path| { - mangle_exported_name(ccx, path, mono_ty, fn_id.node) + exported_name(path, format!("h{}", sip::hash(&(hash_id, mono_ty))), + ccx.link_meta.crateid.version_or_default()) }); debug!("monomorphize_fn mangled to {}", s); diff --git a/src/llvm b/src/llvm index 263c617d660..4b4d0533b4f 160000 --- a/src/llvm +++ b/src/llvm @@ -1 +1 @@ -Subproject commit 263c617d66005999afa27d00809c1568a26112ee +Subproject commit 4b4d0533b4f76cc3fbba31bd9e7ac02e0c738b1d diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp index 2be7c84ab03..32bac73debf 100644 --- a/src/rustllvm/PassWrapper.cpp +++ b/src/rustllvm/PassWrapper.cpp @@ -81,7 +81,9 @@ LLVMRustCreateTargetMachine(const char *triple, TargetOptions Options; Options.NoFramePointerElim = NoFramePointerElim; +#if LLVM_VERSION_MINOR < 5 Options.EnableSegmentedStacks = EnableSegmentedStacks; +#endif Options.FloatABIType = FloatABI::Default; Options.UseSoftFloat = UseSoftFloat; if (UseSoftFloat) { @@ -111,7 +113,11 @@ LLVMRustAddAnalysisPasses(LLVMTargetMachineRef TM, LLVMPassManagerRef PMR, LLVMModuleRef M) { PassManagerBase *PM = unwrap(PMR); +#if LLVM_VERSION_MINOR >= 5 + PM->add(new DataLayoutPass(unwrap(M))); +#else PM->add(new DataLayout(unwrap(M))); +#endif unwrap(TM)->addAnalysisPasses(*PM); } diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 5a00a8034e6..035a39669de 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -129,9 +129,14 @@ extern "C" LLVMValueRef LLVMBuildAtomicCmpXchg(LLVMBuilderRef B, LLVMValueRef target, LLVMValueRef old, LLVMValueRef source, - AtomicOrdering order) { + AtomicOrdering order, + AtomicOrdering failure_order) { return wrap(unwrap(B)->CreateAtomicCmpXchg(unwrap(target), unwrap(old), - unwrap(source), order)); + unwrap(source), order +#if LLVM_VERSION_MINOR >= 5 + , failure_order +#endif + )); } extern "C" LLVMValueRef LLVMBuildAtomicFence(LLVMBuilderRef B, AtomicOrdering order) { return wrap(unwrap(B)->CreateFence(order)); @@ -289,10 +294,9 @@ extern "C" LLVMValueRef LLVMDIBuilderCreateStructType( RunTimeLang, unwrapDI(VTableHolder) #if LLVM_VERSION_MINOR >= 5 - ,UniqueId)); -#else - )); + ,UniqueId #endif + )); } extern "C" LLVMValueRef LLVMDIBuilderCreateMemberType( @@ -318,10 +322,15 @@ extern "C" LLVMValueRef LLVMDIBuilderCreateLexicalBlock( LLVMValueRef Scope, LLVMValueRef File, unsigned Line, - unsigned Col) { + unsigned Col, + unsigned Discriminator) { return wrap(Builder->createLexicalBlock( unwrapDI(Scope), - unwrapDI(File), Line, Col)); + unwrapDI(File), Line, Col +#if LLVM_VERSION_MINOR >= 5 + , Discriminator +#endif + )); } extern "C" LLVMValueRef LLVMDIBuilderCreateStaticVariable( @@ -477,15 +486,16 @@ extern "C" LLVMValueRef LLVMDIBuilderCreateUnionType( unwrapDI(Elements), RunTimeLang #if LLVM_VERSION_MINOR >= 5 - ,UniqueId)); -#else - )); + ,UniqueId #endif + )); } +#if LLVM_VERSION_MINOR < 5 extern "C" void LLVMSetUnnamedAddr(LLVMValueRef Value, LLVMBool Unnamed) { unwrap(Value)->setUnnamedAddr(Unnamed); } +#endif extern "C" LLVMValueRef LLVMDIBuilderCreateTemplateTypeParameter( DIBuilderRef Builder, @@ -620,6 +630,23 @@ LLVMRustLinkInExternalBitcode(LLVMModuleRef dst, char *bc, size_t len) { } #endif +#if LLVM_VERSION_MINOR >= 5 +extern "C" void* +LLVMRustOpenArchive(char *path) { + std::unique_ptr buf; + error_code err = MemoryBuffer::getFile(path, buf); + if (err) { + LLVMRustError = err.message().c_str(); + return NULL; + } + Archive *ret = new Archive(buf.release(), err); + if (err) { + LLVMRustError = err.message().c_str(); + return NULL; + } + return ret; +} +#else extern "C" void* LLVMRustOpenArchive(char *path) { OwningPtr buf; @@ -635,6 +662,7 @@ LLVMRustOpenArchive(char *path) { } return ret; } +#endif extern "C" const char* LLVMRustArchiveReadSection(Archive *ar, char *name, size_t *size) { diff --git a/src/rustllvm/llvm-auto-clean-trigger b/src/rustllvm/llvm-auto-clean-trigger index 3426e823b9f..340a4915277 100644 --- a/src/rustllvm/llvm-auto-clean-trigger +++ b/src/rustllvm/llvm-auto-clean-trigger @@ -1,4 +1,4 @@ # If this file is modified, then llvm will be forcibly cleaned and then rebuilt. # The actual contents of this file do not matter, but to trigger a change on the # build bots then the contents should be changed so git updates the mtime. -2014-02-25 +2014-04-14 diff --git a/src/rustllvm/rustllvm.h b/src/rustllvm/rustllvm.h index f046587052a..42c60e72bab 100644 --- a/src/rustllvm/rustllvm.h +++ b/src/rustllvm/rustllvm.h @@ -12,7 +12,6 @@ #include "llvm/IR/InlineAsm.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" -#include "llvm/Linker.h" #include "llvm/PassManager.h" #include "llvm/IR/InlineAsm.h" #include "llvm/IR/LLVMContext.h" @@ -43,8 +42,6 @@ #include "llvm/Transforms/IPO.h" #include "llvm/Transforms/Instrumentation.h" #include "llvm/Transforms/Vectorize.h" -#include "llvm/DebugInfo.h" -#include "llvm/DIBuilder.h" #include "llvm/Bitcode/ReaderWriter.h" #include "llvm-c/Core.h" #include "llvm-c/BitReader.h" @@ -53,8 +50,14 @@ #if LLVM_VERSION_MINOR >= 5 #include "llvm/IR/IRPrintingPasses.h" +#include "llvm/IR/DebugInfo.h" +#include "llvm/IR/DIBuilder.h" +#include "llvm/Linker/Linker.h" #else #include "llvm/Assembly/PrintModulePass.h" +#include "llvm/DebugInfo.h" +#include "llvm/DIBuilder.h" +#include "llvm/Linker.h" #endif // Used by RustMCJITMemoryManager::getPointerToNamedFunction()