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

rustc: Use link_section, not wasm_custom_section #52353

Merged
merged 1 commit into from
Jul 18, 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
4 changes: 0 additions & 4 deletions src/librustc/hir/check_attr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,6 @@ impl<'a, 'tcx> CheckAttrVisitor<'a, 'tcx> {
self.tcx.sess.span_err(attr.span, "\
must only be attached to foreign modules");
}
} else if attr.check_name("wasm_custom_section") {
if target != Target::Const {
self.tcx.sess.span_err(attr.span, "only allowed on consts");
}
}
}

Expand Down
24 changes: 13 additions & 11 deletions src/librustc/hir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2266,20 +2266,22 @@ pub struct CodegenFnAttrs {
pub export_name: Option<Symbol>,
pub target_features: Vec<Symbol>,
pub linkage: Option<Linkage>,
pub wasm_custom_section: Option<Symbol>,
pub link_section: Option<Symbol>,
}

bitflags! {
#[derive(RustcEncodable, RustcDecodable)]
pub struct CodegenFnAttrFlags: u8 {
const COLD = 0b0000_0001;
const ALLOCATOR = 0b0000_0010;
const UNWIND = 0b0000_0100;
const RUSTC_ALLOCATOR_NOUNWIND = 0b0000_1000;
const NAKED = 0b0001_0000;
const NO_MANGLE = 0b0010_0000;
const RUSTC_STD_INTERNAL_SYMBOL = 0b0100_0000;
const NO_DEBUG = 0b1000_0000;
pub struct CodegenFnAttrFlags: u32 {
const COLD = 1 << 0;
const ALLOCATOR = 1 << 1;
const UNWIND = 1 << 2;
const RUSTC_ALLOCATOR_NOUNWIND = 1 << 3;
const NAKED = 1 << 4;
const NO_MANGLE = 1 << 5;
const RUSTC_STD_INTERNAL_SYMBOL = 1 << 6;
const NO_DEBUG = 1 << 7;
const THREAD_LOCAL = 1 << 8;
const USED = 1 << 9;
}
}

Expand All @@ -2291,7 +2293,7 @@ impl CodegenFnAttrs {
export_name: None,
target_features: vec![],
linkage: None,
wasm_custom_section: None,
link_section: None,
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/librustc/ich/impls_hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1120,7 +1120,7 @@ impl_stable_hash_for!(struct hir::CodegenFnAttrs {
export_name,
target_features,
linkage,
wasm_custom_section,
link_section,
});

impl<'hir> HashStable<StableHashingContext<'hir>> for hir::CodegenFnAttrFlags
Expand Down
5 changes: 0 additions & 5 deletions src/librustc/middle/dead.rs
Original file line number Diff line number Diff line change
Expand Up @@ -313,11 +313,6 @@ fn has_allow_dead_code_or_lang_attr(tcx: TyCtxt,
return true;
}

// These constants are special for wasm
if attr::contains_name(attrs, "wasm_custom_section") {
return true;
}

tcx.lint_level_at_node(lint::builtin::DEAD_CODE, id).0 == lint::Allow
}

Expand Down
7 changes: 2 additions & 5 deletions src/librustc/mir/mono.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,6 @@ pub enum MonoItem<'tcx> {
Fn(Instance<'tcx>),
Static(DefId),
GlobalAsm(NodeId),
CustomSection(DefId),
}

impl<'tcx> MonoItem<'tcx> {
Expand All @@ -38,8 +37,7 @@ impl<'tcx> MonoItem<'tcx> {
// Conservatively estimate the size of a static declaration
// or assembly to be 1.
MonoItem::Static(_) |
MonoItem::GlobalAsm(_) |
MonoItem::CustomSection(_) => 1,
MonoItem::GlobalAsm(_) => 1,
}
}
}
Expand All @@ -54,8 +52,7 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for MonoItem<'tcx> {
MonoItem::Fn(ref instance) => {
instance.hash_stable(hcx, hasher);
}
MonoItem::Static(def_id) |
MonoItem::CustomSection(def_id) => {
MonoItem::Static(def_id) => {
def_id.hash_stable(hcx, hasher);
}
MonoItem::GlobalAsm(node_id) => {
Expand Down
66 changes: 9 additions & 57 deletions src/librustc_codegen_llvm/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ use back::link;
use back::write::{self, OngoingCodegen, create_target_machine};
use llvm::{ContextRef, ModuleRef, ValueRef, Vector, get_param};
use llvm;
use libc::c_uint;
use metadata;
use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
use rustc::middle::lang_items::StartFnLangItem;
Expand Down Expand Up @@ -87,8 +86,7 @@ use std::sync::mpsc;
use syntax_pos::Span;
use syntax_pos::symbol::InternedString;
use syntax::attr;
use rustc::hir;
use syntax::ast;
use rustc::hir::{self, CodegenFnAttrs};

use mir::operand::OperandValue;

Expand Down Expand Up @@ -513,17 +511,14 @@ pub fn codegen_instance<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, instance: Instance<'
mir::codegen_mir(cx, lldecl, &mir, instance, sig);
}

pub fn set_link_section(cx: &CodegenCx,
llval: ValueRef,
attrs: &[ast::Attribute]) {
if let Some(sect) = attr::first_attr_value_str_by_name(attrs, "link_section") {
if contains_null(&sect.as_str()) {
cx.sess().fatal(&format!("Illegal null byte in link_section value: `{}`", &sect));
}
unsafe {
let buf = CString::new(sect.as_str().as_bytes()).unwrap();
llvm::LLVMSetSection(llval, buf.as_ptr());
}
pub fn set_link_section(llval: ValueRef, attrs: &CodegenFnAttrs) {
let sect = match attrs.link_section {
Some(name) => name,
None => return,
};
unsafe {
let buf = CString::new(sect.as_str().as_bytes()).unwrap();
llvm::LLVMSetSection(llval, buf.as_ptr());
}
}

Expand Down Expand Up @@ -613,10 +608,6 @@ fn maybe_create_entry_wrapper(cx: &CodegenCx) {
}
}

fn contains_null(s: &str) -> bool {
s.bytes().any(|b| b == 0)
}

fn write_metadata<'a, 'gcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>,
llmod_id: &str,
link_meta: &LinkMeta)
Expand Down Expand Up @@ -1369,42 +1360,3 @@ mod temp_stable_hash_impls {
}
}
}

pub fn define_custom_section(cx: &CodegenCx, def_id: DefId) {
use rustc::mir::interpret::GlobalId;

assert!(cx.tcx.sess.opts.target_triple.triple().starts_with("wasm32"));

info!("loading wasm section {:?}", def_id);

let section = cx.tcx.codegen_fn_attrs(def_id).wasm_custom_section.unwrap();

let instance = ty::Instance::mono(cx.tcx, def_id);
let cid = GlobalId {
instance,
promoted: None
};
let param_env = ty::ParamEnv::reveal_all();
let val = cx.tcx.const_eval(param_env.and(cid)).unwrap();
let alloc = cx.tcx.const_value_to_allocation(val);

unsafe {
let section = llvm::LLVMMDStringInContext(
cx.llcx,
section.as_str().as_ptr() as *const _,
section.as_str().len() as c_uint,
);
let alloc = llvm::LLVMMDStringInContext(
cx.llcx,
alloc.bytes.as_ptr() as *const _,
alloc.bytes.len() as c_uint,
);
let data = [section, alloc];
let meta = llvm::LLVMMDNodeInContext(cx.llcx, data.as_ptr(), 2);
llvm::LLVMAddNamedMetadataOperand(
cx.llmod,
"wasm.custom_sections\0".as_ptr() as *const _,
meta,
);
}
}
45 changes: 35 additions & 10 deletions src/librustc_codegen_llvm/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use libc::c_uint;
use llvm;
use llvm::{SetUnnamedAddr};
use llvm::{ValueRef, True};
Expand All @@ -24,11 +25,9 @@ use type_of::LayoutLlvmExt;
use rustc::ty;
use rustc::ty::layout::{Align, LayoutOf};

use rustc::hir;
use rustc::hir::{self, CodegenFnAttrFlags};

use std::ffi::{CStr, CString};
use syntax::ast;
use syntax::attr;

pub fn ptrcast(val: ValueRef, ty: Type) -> ValueRef {
unsafe {
Expand Down Expand Up @@ -244,18 +243,19 @@ pub fn get_static(cx: &CodegenCx, def_id: DefId) -> ValueRef {
}

pub fn codegen_static<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
def_id: DefId,
is_mutable: bool,
attrs: &[ast::Attribute]) {
def_id: DefId,
is_mutable: bool) {
unsafe {
let g = get_static(cx, def_id);
let attrs = cx.tcx.codegen_fn_attrs(def_id);

let (v, alloc) = match ::mir::codegen_static_initializer(cx, def_id) {
Ok(v) => v,
// Error has already been reported
Err(_) => return,
};

let g = get_static(cx, def_id);

// boolean SSA values are i1, but they have to be stored in i8 slots,
// otherwise some LLVM optimization passes don't work as expected
let mut val_llty = val_ty(v);
Expand Down Expand Up @@ -307,7 +307,7 @@ pub fn codegen_static<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,

debuginfo::create_global_var_metadata(cx, def_id, g);

if attr::contains_name(attrs, "thread_local") {
if attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL) {
llvm::set_thread_local_mode(g, cx.tls_model);

// Do not allow LLVM to change the alignment of a TLS on macOS.
Expand Down Expand Up @@ -349,9 +349,34 @@ pub fn codegen_static<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
}
}

base::set_link_section(cx, g, attrs);

if attr::contains_name(attrs, "used") {
// Wasm statics with custom link sections get special treatment as they
// go into custom sections of the wasm executable.
if cx.tcx.sess.opts.target_triple.triple().starts_with("wasm32") {
if let Some(section) = attrs.link_section {
let section = llvm::LLVMMDStringInContext(
cx.llcx,
section.as_str().as_ptr() as *const _,
section.as_str().len() as c_uint,
);
let alloc = llvm::LLVMMDStringInContext(
cx.llcx,
alloc.bytes.as_ptr() as *const _,
alloc.bytes.len() as c_uint,
);
let data = [section, alloc];
let meta = llvm::LLVMMDNodeInContext(cx.llcx, data.as_ptr(), 2);
llvm::LLVMAddNamedMetadataOperand(
cx.llmod,
"wasm.custom_sections\0".as_ptr() as *const _,
meta,
);
}
} else {
base::set_link_section(g, &attrs);
}

if attrs.flags.contains(CodegenFnAttrFlags::USED) {
// This static will be stored in the llvm.used variable which is an array of i8*
let cast = llvm::LLVMConstPointerCast(g, Type::i8p(cx).to_ref());
cx.used_statics.borrow_mut().push(cast);
Expand Down
15 changes: 3 additions & 12 deletions src/librustc_codegen_llvm/mono_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,7 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> {
bug!("Expected Def::Static for {:?}, found nothing", def_id)
}
};
let attrs = tcx.get_attrs(def_id);

consts::codegen_static(&cx, def_id, is_mutable, &attrs);
consts::codegen_static(&cx, def_id, is_mutable);
}
MonoItem::GlobalAsm(node_id) => {
let item = cx.tcx.hir.expect_item(node_id);
Expand All @@ -66,9 +64,6 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> {
span_bug!(item.span, "Mismatch between hir::Item type and MonoItem type")
}
}
MonoItem::CustomSection(def_id) => {
base::define_custom_section(cx, def_id);
}
MonoItem::Fn(instance) => {
base::codegen_instance(&cx, instance);
}
Expand Down Expand Up @@ -100,7 +95,6 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> {
MonoItem::Fn(instance) => {
predefine_fn(cx, instance, linkage, visibility, &symbol_name);
}
MonoItem::CustomSection(..) => {}
MonoItem::GlobalAsm(..) => {}
}

Expand All @@ -120,9 +114,6 @@ pub trait MonoItemExt<'a, 'tcx>: fmt::Debug + BaseMonoItemExt<'a, 'tcx> {
MonoItem::Static(id) => {
format!("Static({:?})", id)
}
MonoItem::CustomSection(id) => {
format!("CustomSection({:?})", id)
}
MonoItem::GlobalAsm(id) => {
format!("GlobalAsm({:?})", id)
}
Expand Down Expand Up @@ -164,10 +155,10 @@ fn predefine_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
!instance.substs.has_param_types());

let mono_ty = instance.ty(cx.tcx);
let attrs = instance.def.attrs(cx.tcx);
let attrs = cx.tcx.codegen_fn_attrs(instance.def_id());
let lldecl = declare::declare_fn(cx, symbol_name, mono_ty);
unsafe { llvm::LLVMRustSetLinkage(lldecl, base::linkage_to_llvm(linkage)) };
base::set_link_section(cx, lldecl, &attrs);
base::set_link_section(lldecl, &attrs);
if linkage == Linkage::LinkOnceODR ||
linkage == Linkage::WeakODR {
llvm::SetUniqueComdat(cx.llmod, lldecl);
Expand Down
10 changes: 0 additions & 10 deletions src/librustc_mir/monomorphize/collector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -414,9 +414,6 @@ fn collect_items_rec<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
MonoItem::GlobalAsm(..) => {
recursion_depth_reset = None;
}
MonoItem::CustomSection(..) => {
recursion_depth_reset = None;
}
}

record_accesses(tcx, starting_point, &neighbors[..], inlining_map);
Expand Down Expand Up @@ -993,13 +990,6 @@ impl<'b, 'a, 'v> ItemLikeVisitor<'v> for RootCollector<'b, 'a, 'v> {
hir::ItemKind::Const(..) => {
// const items only generate mono items if they are
// actually used somewhere. Just declaring them is insufficient.

let def_id = self.tcx.hir.local_def_id(item.id);
if self.tcx.sess.opts.target_triple.triple().starts_with("wasm32") &&
self.tcx.codegen_fn_attrs(def_id).wasm_custom_section.is_some()
{
self.output.push(MonoItem::CustomSection(def_id));
}
}
hir::ItemKind::Fn(..) => {
let def_id = self.tcx.hir.local_def_id(item.id);
Expand Down
Loading