Skip to content

Commit

Permalink
rustc: Use link_section, not wasm_custom_section
Browse files Browse the repository at this point in the history
This commit transitions definitions of custom sections on the wasm target from
the unstable `#[wasm_custom_section]` attribute to the
already-stable-for-other-targets `#[link_section]` attribute. Mostly the same
restrictions apply as before, except that this now applies only to statics.

Closes #51088
  • Loading branch information
alexcrichton committed Jul 16, 2018
1 parent 50702b2 commit b7ef674
Show file tree
Hide file tree
Showing 26 changed files with 147 additions and 328 deletions.
4 changes: 0 additions & 4 deletions src/librustc/hir/check_attr.rs
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
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
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
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
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
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
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
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
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

0 comments on commit b7ef674

Please sign in to comment.