Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make globals with private linkage unnamed. Fixes #50862. #51007

Merged
merged 2 commits into from
Aug 7, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions src/librustc_codegen_llvm/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -541,11 +541,23 @@ unsafe fn optimize(cgcx: &CodegenContext,
};

if config.verify_llvm_ir { assert!(addpass("verify")); }

// Some options cause LLVM bitcode to be emitted, which uses ThinLTOBuffers, so we need
// to make sure we run LLVM's NameAnonGlobals pass when emitting bitcode; otherwise
// we'll get errors in LLVM.
let using_thin_buffers = llvm::LLVMRustThinLTOAvailable() && (config.emit_bc
|| config.obj_is_bitcode || config.emit_bc_compressed || config.embed_bitcode);
let mut have_name_anon_globals_pass = false;
if !config.no_prepopulate_passes {
llvm::LLVMRustAddAnalysisPasses(tm, fpm, llmod);
llvm::LLVMRustAddAnalysisPasses(tm, mpm, llmod);
let opt_level = config.opt_level.unwrap_or(llvm::CodeGenOptLevel::None);
let prepare_for_thin_lto = cgcx.lto == Lto::Thin || cgcx.lto == Lto::ThinLocal;
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);
Expand All @@ -557,6 +569,9 @@ unsafe fn optimize(cgcx: &CodegenContext,
diag_handler.warn(&format!("unknown pass `{}`, ignoring",
pass));
}
if pass == "name-anon-globals" {
have_name_anon_globals_pass = true;
}
}

for pass in &cgcx.plugin_passes {
Expand All @@ -565,6 +580,22 @@ unsafe fn optimize(cgcx: &CodegenContext,
`{}` but LLVM does not \
recognize it", pass));
}
if pass == "name-anon-globals" {
have_name_anon_globals_pass = true;
}
}

if using_thin_buffers && !have_name_anon_globals_pass {
// As described above, this will probably cause an error in LLVM
if config.no_prepopulate_passes {
diag_handler.err("The current compilation is going to use thin LTO buffers \
without running LLVM's NameAnonGlobals pass. \
This will likely cause errors in LLVM. Consider adding \
-C passes=name-anon-globals to the compiler command line.");
} else {
bug!("We are using thin LTO buffers without running the NameAnonGlobals pass. \
This will likely cause errors in LLVM and shoud never happen.");
}
}
}

Expand Down
20 changes: 13 additions & 7 deletions src/librustc_codegen_llvm/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,16 +66,22 @@ pub fn addr_of_mut(
cx: &CodegenCx<'ll, '_>,
cv: &'ll Value,
align: Align,
kind: &str,
kind: Option<&str>,
) -> &'ll Value {
unsafe {
let name = cx.generate_local_symbol_name(kind);
let gv = declare::define_global(cx, &name[..], val_ty(cv)).unwrap_or_else(||{
bug!("symbol `{}` is already defined", name);
});
let gv = match kind {
Some(kind) if !cx.tcx.sess.fewer_names() => {
let name = cx.generate_local_symbol_name(kind);
let gv = declare::define_global(cx, &name[..], val_ty(cv)).unwrap_or_else(||{
bug!("symbol `{}` is already defined", name);
});
llvm::LLVMRustSetLinkage(gv, llvm::Linkage::PrivateLinkage);
gv
},
_ => declare::define_private_global(cx, val_ty(cv)),
};
llvm::LLVMSetInitializer(gv, cv);
set_global_alignment(cx, gv, align);
llvm::LLVMRustSetLinkage(gv, llvm::Linkage::PrivateLinkage);
SetUnnamedAddr(gv, true);
gv
}
Expand All @@ -85,7 +91,7 @@ pub fn addr_of(
cx: &CodegenCx<'ll, '_>,
cv: &'ll Value,
align: Align,
kind: &str,
kind: Option<&str>,
) -> &'ll Value {
if let Some(&gv) = cx.const_globals.borrow().get(&cv) {
unsafe {
Expand Down
10 changes: 9 additions & 1 deletion src/librustc_codegen_llvm/declare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ use value::Value;

use std::ffi::CString;


/// Declare a global value.
///
/// If there’s a value with the same name already declared, the function will
Expand Down Expand Up @@ -170,6 +169,15 @@ pub fn define_global(cx: &CodegenCx<'ll, '_>, name: &str, ty: &'ll Type) -> Opti
}
}

/// Declare a private global
///
/// Use this function when you intend to define a global without a name.
pub fn define_private_global(cx: &CodegenCx<'ll, '_>, ty: &'ll Type) -> &'ll Value {
unsafe {
llvm::LLVMRustInsertPrivateGlobal(cx.llmod, ty)
}
}

/// Declare a Rust function with an intention to define it.
///
/// Use this function when you intend to define a function. This function will
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 @@ -622,6 +622,7 @@ extern "C" {
pub fn LLVMAddGlobal(M: &'a Module, Ty: &'a Type, Name: *const c_char) -> &'a Value;
pub fn LLVMGetNamedGlobal(M: &Module, Name: *const c_char) -> Option<&Value>;
pub fn LLVMRustGetOrInsertGlobal(M: &'a Module, Name: *const c_char, T: &'a Type) -> &'a Value;
pub fn LLVMRustInsertPrivateGlobal(M: &'a Module, T: &'a Type) -> &'a Value;
pub fn LLVMGetFirstGlobal(M: &Module) -> Option<&Value>;
pub fn LLVMGetNextGlobal(GlobalVar: &Value) -> Option<&Value>;
pub fn LLVMDeleteGlobal(GlobalVar: &Value);
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_codegen_llvm/meth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ pub fn get_vtable(

let vtable_const = C_struct(cx, &components, false);
let align = cx.data_layout().pointer_align;
let vtable = consts::addr_of(cx, vtable_const, align, "vtable");
let vtable = consts::addr_of(cx, vtable_const, align, Some("vtable"));

debuginfo::create_vtable_metadata(cx, ty, vtable);

Expand Down
4 changes: 2 additions & 2 deletions src/librustc_codegen_llvm/mir/block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -377,7 +377,7 @@ impl FunctionCx<'a, 'll, 'tcx> {
let file_line_col = consts::addr_of(bx.cx,
file_line_col,
align,
"panic_bounds_check_loc");
Some("panic_bounds_check_loc"));
(lang_items::PanicBoundsCheckFnLangItem,
vec![file_line_col, index, len])
}
Expand All @@ -391,7 +391,7 @@ impl FunctionCx<'a, 'll, 'tcx> {
let msg_file_line_col = consts::addr_of(bx.cx,
msg_file_line_col,
align,
"panic_loc");
Some("panic_loc"));
(lang_items::PanicFnLangItem,
vec![msg_file_line_col])
}
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_codegen_llvm/mir/constant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,9 @@ pub fn scalar_to_llvm(
Some(AllocType::Memory(alloc)) => {
let init = const_alloc_to_llvm(cx, alloc);
if alloc.runtime_mutability == Mutability::Mutable {
consts::addr_of_mut(cx, init, alloc.align, "byte_str")
consts::addr_of_mut(cx, init, alloc.align, None)
} else {
consts::addr_of(cx, init, alloc.align, "byte_str")
consts::addr_of(cx, init, alloc.align, None)
}
}
Some(AllocType::Function(fn_instance)) => {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_codegen_llvm/mir/place.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ impl PlaceRef<'ll, 'tcx> {
offset: Size,
) -> PlaceRef<'ll, 'tcx> {
let init = const_alloc_to_llvm(bx.cx, alloc);
let base_addr = consts::addr_of(bx.cx, init, layout.align, "byte_str");
let base_addr = consts::addr_of(bx.cx, init, layout.align, None);

let llval = unsafe { LLVMConstInBoundsGEP(
consts::bitcast(base_addr, Type::i8p(bx.cx)),
Expand Down
10 changes: 10 additions & 0 deletions src/rustllvm/RustWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
#include "llvm/IR/DebugInfoMetadata.h"
#include "llvm/IR/DiagnosticInfo.h"
#include "llvm/IR/DiagnosticPrinter.h"
#include "llvm/IR/GlobalVariable.h"
#include "llvm/IR/Instructions.h"
#include "llvm/Object/Archive.h"
#include "llvm/Object/ObjectFile.h"
Expand Down Expand Up @@ -116,6 +117,15 @@ LLVMRustGetOrInsertGlobal(LLVMModuleRef M, const char *Name, LLVMTypeRef Ty) {
return wrap(unwrap(M)->getOrInsertGlobal(Name, unwrap(Ty)));
}

extern "C" LLVMValueRef
LLVMRustInsertPrivateGlobal(LLVMModuleRef M, LLVMTypeRef Ty) {
return wrap(new GlobalVariable(*unwrap(M),
unwrap(Ty),
false,
GlobalValue::PrivateLinkage,
nullptr));
}

extern "C" LLVMTypeRef LLVMRustMetadataTypeInContext(LLVMContextRef C) {
return wrap(Type::getMetadataTy(*unwrap(C)));
}
Expand Down
4 changes: 2 additions & 2 deletions src/test/codegen/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@
// CHECK: @STATIC = {{.*}}, align 4

// This checks the constants from inline_enum_const
// CHECK: @byte_str.{{[0-9]+}} = {{.*}}, align 2
// CHECK: @{{[0-9]+}} = {{.*}}, align 2

// This checks the constants from {low,high}_align_const, they share the same
// constant, but the alignment differs, so the higher one should be used
// CHECK: [[LOW_HIGH:@byte_str.[0-9]+]] = {{.*}}, align 4
// CHECK: [[LOW_HIGH:@[0-9]+]] = {{.*}}, align 4

#[derive(Copy, Clone)]

Expand Down
2 changes: 1 addition & 1 deletion src/test/codegen/remap_path_prefix/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ mod aux_mod;
include!("aux_mod.rs");

// Here we check that the expansion of the file!() macro is mapped.
// CHECK: @byte_str.1 = private unnamed_addr constant <{ [34 x i8] }> <{ [34 x i8] c"/the/src/remap_path_prefix/main.rs" }>, align 1
// CHECK: @0 = private unnamed_addr constant <{ [34 x i8] }> <{ [34 x i8] c"/the/src/remap_path_prefix/main.rs" }>, align 1
pub static FILE_PATH: &'static str = file!();

fn main() {
Expand Down
13 changes: 0 additions & 13 deletions src/test/run-make-fulldeps/symbols-are-reasonable/Makefile

This file was deleted.

21 changes: 0 additions & 21 deletions src/test/run-make-fulldeps/symbols-are-reasonable/lib.rs

This file was deleted.

2 changes: 1 addition & 1 deletion src/test/run-pass-fulldeps/myriad-closures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
// See https://github.com/rust-lang/rust/issues/34793 for more information.

// Make sure we don't optimize anything away:
// compile-flags: -C no-prepopulate-passes
// compile-flags: -C no-prepopulate-passes -Cpasses=name-anon-globals

// Expand something exponentially
macro_rules! go_bacterial {
Expand Down
2 changes: 1 addition & 1 deletion src/test/run-pass/issue-38226.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

// Need -Cno-prepopulate-passes to really disable inlining, otherwise the faulty
// code gets optimized out:
// compile-flags: -Cno-prepopulate-passes
// compile-flags: -Cno-prepopulate-passes -Cpasses=name-anon-globals

extern crate issue_38226_aux;

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/feature-gate-unwind-attributes.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: -C no-prepopulate-passes
// compile-flags: -C no-prepopulate-passes -Cpasses=name-anon-globals

#![crate_type = "lib"]

Expand Down