Skip to content

Commit

Permalink
Upgrade LLVM
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
alexcrichton committed Apr 17, 2014
1 parent 903fbd2 commit 30ff17f
Show file tree
Hide file tree
Showing 13 changed files with 89 additions and 35 deletions.
4 changes: 0 additions & 4 deletions configure
Original file line number Diff line number Diff line change
Expand Up @@ -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.)
Expand Down
6 changes: 4 additions & 2 deletions src/librustc/lib/llvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand Down
8 changes: 4 additions & 4 deletions src/librustc/middle/trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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") {
Expand All @@ -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); }
})
}
Expand Down
5 changes: 3 additions & 2 deletions src/librustc/middle/trans/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
6 changes: 4 additions & 2 deletions src/librustc/middle/trans/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
6 changes: 4 additions & 2 deletions src/librustc/middle/trans/debuginfo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 });
Expand Down Expand Up @@ -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 {
Expand Down
15 changes: 14 additions & 1 deletion src/librustc/middle/trans/intrinsic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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" => {
Expand Down
7 changes: 4 additions & 3 deletions src/librustc/middle/trans/monomorphize.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand All @@ -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,
Expand Down Expand Up @@ -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);

Expand Down
2 changes: 1 addition & 1 deletion src/llvm
Submodule llvm updated 3201 files
6 changes: 6 additions & 0 deletions src/rustllvm/PassWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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);
}

Expand Down
48 changes: 38 additions & 10 deletions src/rustllvm/RustWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down Expand Up @@ -289,10 +294,9 @@ extern "C" LLVMValueRef LLVMDIBuilderCreateStructType(
RunTimeLang,
unwrapDI<DIType>(VTableHolder)
#if LLVM_VERSION_MINOR >= 5
,UniqueId));
#else
));
,UniqueId
#endif
));
}

extern "C" LLVMValueRef LLVMDIBuilderCreateMemberType(
Expand All @@ -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<DIDescriptor>(Scope),
unwrapDI<DIFile>(File), Line, Col));
unwrapDI<DIFile>(File), Line, Col
#if LLVM_VERSION_MINOR >= 5
, Discriminator
#endif
));
}

extern "C" LLVMValueRef LLVMDIBuilderCreateStaticVariable(
Expand Down Expand Up @@ -477,15 +486,16 @@ extern "C" LLVMValueRef LLVMDIBuilderCreateUnionType(
unwrapDI<DIArray>(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<GlobalValue>(Value)->setUnnamedAddr(Unnamed);
}
#endif

extern "C" LLVMValueRef LLVMDIBuilderCreateTemplateTypeParameter(
DIBuilderRef Builder,
Expand Down Expand Up @@ -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<MemoryBuffer> 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<MemoryBuffer> buf;
Expand All @@ -635,6 +662,7 @@ LLVMRustOpenArchive(char *path) {
}
return ret;
}
#endif

extern "C" const char*
LLVMRustArchiveReadSection(Archive *ar, char *name, size_t *size) {
Expand Down
2 changes: 1 addition & 1 deletion src/rustllvm/llvm-auto-clean-trigger
Original file line number Diff line number Diff line change
@@ -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
9 changes: 6 additions & 3 deletions src/rustllvm/rustllvm.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand All @@ -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()
Expand Down

0 comments on commit 30ff17f

Please sign in to comment.