Skip to content

Commit

Permalink
Auto merge of #56358 - nikic:mergefunc-aliases, r=rkruppe
Browse files Browse the repository at this point in the history
Enable -mergefunc-use-aliases

If the Rust LLVM fork is used, enable the -mergefunc-use-aliases
flag, which will create aliases for merged functions, rather than
inserting a call from one to the other.

A number of codegen tests needed to be adjusted, because functions
that previously fell below the thunk limit are now being merged.
Merging is prevented in various ways now.

I expect that this is going to break something, somewhere, because
it isn't able to deal with aliases properly, but we won't find out
until we try :)

This fixes #52651.

r? @rkruppe
  • Loading branch information
bors committed Dec 3, 2018
2 parents b817d0b + 850d2f1 commit a563ceb
Show file tree
Hide file tree
Showing 9 changed files with 26 additions and 10 deletions.
9 changes: 5 additions & 4 deletions src/librustc_codegen_llvm/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,15 +371,16 @@ pub(crate) unsafe fn optimize(cgcx: &CodegenContext<LlvmCodegenBackend>,
.unwrap_or(llvm::CodeGenOptLevel::None);
let prepare_for_thin_lto = cgcx.lto == Lto::Thin || cgcx.lto == Lto::ThinLocal ||
(cgcx.lto != Lto::Fat && cgcx.opts.debugging_opts.cross_lang_lto.enabled());
with_llvm_pmb(llmod, &config, opt_level, prepare_for_thin_lto, &mut |b| {
llvm::LLVMPassManagerBuilderPopulateFunctionPassManager(b, fpm);
llvm::LLVMPassManagerBuilderPopulateModulePassManager(b, mpm);
});

have_name_anon_globals_pass = have_name_anon_globals_pass || prepare_for_thin_lto;
if using_thin_buffers && !prepare_for_thin_lto {
assert!(addpass("name-anon-globals"));
have_name_anon_globals_pass = true;
}
with_llvm_pmb(llmod, &config, opt_level, prepare_for_thin_lto, &mut |b| {
llvm::LLVMPassManagerBuilderPopulateFunctionPassManager(b, fpm);
llvm::LLVMPassManagerBuilderPopulateModulePassManager(b, mpm);
})
}

for pass in &config.passes {
Expand Down
1 change: 1 addition & 0 deletions src/librustc_codegen_llvm/llvm/ffi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1358,6 +1358,7 @@ extern "C" {
pub fn LLVMRustDebugMetadataVersion() -> u32;
pub fn LLVMRustVersionMajor() -> u32;
pub fn LLVMRustVersionMinor() -> u32;
pub fn LLVMRustIsRustLLVM() -> bool;

pub fn LLVMRustAddModuleFlag(M: &Module, name: *const c_char, value: u32);

Expand Down
3 changes: 3 additions & 0 deletions src/librustc_codegen_llvm/llvm_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ unsafe fn configure_llvm(sess: &Session) {
if sess.opts.debugging_opts.disable_instrumentation_preinliner {
add("-disable-preinline");
}
if llvm::LLVMRustIsRustLLVM() {
add("-mergefunc-use-aliases");
}

for arg in &sess.opts.cg.llvm_args {
add(&(*arg));
Expand Down
2 changes: 1 addition & 1 deletion src/rustllvm/PassWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ static Optional<Reloc::Model> fromRust(LLVMRustRelocMode RustReloc) {
report_fatal_error("Bad RelocModel.");
}

#if LLVM_RUSTLLVM
#ifdef LLVM_RUSTLLVM
/// getLongestEntryLength - Return the length of the longest entry in the table.
///
static size_t getLongestEntryLength(ArrayRef<SubtargetFeatureKV> Table) {
Expand Down
8 changes: 8 additions & 0 deletions src/rustllvm/RustWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -533,6 +533,14 @@ extern "C" uint32_t LLVMRustVersionMinor() { return LLVM_VERSION_MINOR; }

extern "C" uint32_t LLVMRustVersionMajor() { return LLVM_VERSION_MAJOR; }

extern "C" bool LLVMRustIsRustLLVM() {
#ifdef LLVM_RUSTLLVM
return 1;
#else
return 0;
#endif
}

extern "C" void LLVMRustAddModuleFlag(LLVMModuleRef M, const char *Name,
uint32_t Value) {
unwrap(M)->addModuleFlag(Module::Warning, Name, Value);
Expand Down
2 changes: 2 additions & 0 deletions src/test/codegen/export-no-mangle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-flags: -C no-prepopulate-passes

#![crate_type = "lib"]

mod private {
Expand Down
4 changes: 2 additions & 2 deletions src/test/codegen/external-no-mangle-fns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

// compile-flags: -O
// compile-flags: -C no-prepopulate-passes
// `#[no_mangle]`d functions always have external linkage, i.e. no `internal` in their `define`s

#![crate_type = "lib"]
Expand Down Expand Up @@ -43,7 +43,7 @@ const HIDDEN: () = {
};

// The surrounding item should not accidentally become external
// CHECK: define internal {{.*}} void @_ZN22external_no_mangle_fns1x
// CHECK: define internal{{.*}} void @_ZN22external_no_mangle_fns1x
#[inline(never)]
fn x() {
// CHECK: define void @g()
Expand Down
4 changes: 2 additions & 2 deletions src/test/codegen/issue-45222.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,6 @@ fn foo3r(n: u64) -> u64 {
// CHECK-LABEL: @check_foo3r
#[no_mangle]
pub fn check_foo3r() -> u64 {
// CHECK: ret i64 500005000000000
foo3r(100000)
// CHECK: ret i64 500050000000
foo3r(10000)
}
3 changes: 2 additions & 1 deletion src/test/codegen/match-optimizes-away.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

pub enum Three { A, B, C }

#[repr(u16)]
pub enum Four { A, B, C, D }

#[no_mangle]
Expand All @@ -32,7 +33,7 @@ pub fn three_valued(x: Three) -> Three {
pub fn four_valued(x: Four) -> Four {
// CHECK-LABEL: @four_valued
// CHECK-NEXT: {{^.*:$}}
// CHECK-NEXT: ret i8 %0
// CHECK-NEXT: ret i16 %0
match x {
Four::A => Four::A,
Four::B => Four::B,
Expand Down

0 comments on commit a563ceb

Please sign in to comment.