From f40985b9616357690577c99c0d0cb09c37dc8040 Mon Sep 17 00:00:00 2001 From: "A.J. Gardner" Date: Tue, 21 Mar 2017 10:03:52 -0500 Subject: [PATCH] Add new TransItem for global_asm trans --- src/librustc_trans/asm.rs | 8 ++++++++ src/librustc_trans/collector.rs | 10 +++++++++- src/librustc_trans/partitioning.rs | 23 ++++++++++++--------- src/librustc_trans/symbol_map.rs | 5 ++++- src/librustc_trans/trans_item.rs | 32 ++++++++++++++++++++++++++---- 5 files changed, 63 insertions(+), 15 deletions(-) diff --git a/src/librustc_trans/asm.rs b/src/librustc_trans/asm.rs index 12e4e57964f98..ba04897609d48 100644 --- a/src/librustc_trans/asm.rs +++ b/src/librustc_trans/asm.rs @@ -124,3 +124,11 @@ pub fn trans_inline_asm<'a, 'tcx>( llvm::LLVMMDNodeInContext(bcx.ccx.llcx(), &val, 1)); } } + +pub fn trans_global_asm<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, + ga: &hir::GlobalAsm) { + let asm = CString::new(ga.asm.as_str().as_bytes()).unwrap(); + unsafe { + llvm::LLVMSetModuleInlineAsm(ccx.llmod(), asm.as_ptr()); + } +} diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs index 025aea2c5bddd..d8bc2e72b15ba 100644 --- a/src/librustc_trans/collector.rs +++ b/src/librustc_trans/collector.rs @@ -361,6 +361,9 @@ fn collect_items_rec<'a, 'tcx: 'a>(scx: &SharedCrateContext<'a, 'tcx>, collect_neighbours(scx, instance, &mut neighbors); } + TransItem::GlobalAsm(..) => { + recursion_depth_reset = None; + } } record_inlining_canditates(scx.tcx(), starting_point, &neighbors[..], inlining_map); @@ -1157,7 +1160,6 @@ impl<'b, 'a, 'v> ItemLikeVisitor<'v> for RootCollector<'b, 'a, 'v> { hir::ItemExternCrate(..) | hir::ItemUse(..) | hir::ItemForeignMod(..) | - hir::ItemGlobalAsm(..) | hir::ItemTy(..) | hir::ItemDefaultImpl(..) | hir::ItemTrait(..) | @@ -1188,6 +1190,12 @@ impl<'b, 'a, 'v> ItemLikeVisitor<'v> for RootCollector<'b, 'a, 'v> { } } } + hir::ItemGlobalAsm(..) => { + debug!("RootCollector: ItemGlobalAsm({})", + def_id_to_string(self.scx.tcx(), + self.scx.tcx().hir.local_def_id(item.id))); + self.output.push(TransItem::GlobalAsm(item.id)); + } hir::ItemStatic(..) => { debug!("RootCollector: ItemStatic({})", def_id_to_string(self.scx.tcx(), diff --git a/src/librustc_trans/partitioning.rs b/src/librustc_trans/partitioning.rs index cc9fd8f46f6f0..afb4b9960c7e9 100644 --- a/src/librustc_trans/partitioning.rs +++ b/src/librustc_trans/partitioning.rs @@ -185,15 +185,16 @@ impl<'tcx> CodegenUnit<'tcx> { symbol_name.len().hash(&mut state); symbol_name.hash(&mut state); let exported = match item { - TransItem::Fn(ref instance) => { + TransItem::Fn(ref instance) => { let node_id = scx.tcx().hir.as_local_node_id(instance.def); node_id.map(|node_id| exported_symbols.contains(&node_id)) - .unwrap_or(false) - } - TransItem::Static(node_id) => { + .unwrap_or(false) + } + TransItem::Static(node_id) => { exported_symbols.contains(&node_id) - } - TransItem::DropGlue(..) => false, + } + TransItem::DropGlue(..) => false, + TransItem::GlobalAsm(..) => true, }; exported.hash(&mut state); } @@ -243,7 +244,9 @@ impl<'tcx> CodegenUnit<'tcx> { TransItem::Fn(instance) => { tcx.hir.as_local_node_id(instance.def) } - TransItem::Static(node_id) => Some(node_id), + TransItem::Static(node_id) | TransItem::GlobalAsm(node_id) => { + Some(node_id) + } TransItem::DropGlue(_) => None, } } @@ -339,7 +342,8 @@ fn place_root_translation_items<'a, 'tcx, I>(scx: &SharedCrateContext<'a, 'tcx>, None => { match trans_item { TransItem::Fn(..) | - TransItem::Static(..) => llvm::ExternalLinkage, + TransItem::Static(..) | + TransItem::GlobalAsm(..) => llvm::ExternalLinkage, TransItem::DropGlue(..) => unreachable!(), } } @@ -477,7 +481,8 @@ fn characteristic_def_id_of_trans_item<'a, 'tcx>(scx: &SharedCrateContext<'a, 't Some(instance.def) } TransItem::DropGlue(dg) => characteristic_def_id_of_type(dg.ty()), - TransItem::Static(node_id) => Some(tcx.hir.local_def_id(node_id)), + TransItem::Static(node_id) | + TransItem::GlobalAsm(node_id) => Some(tcx.hir.local_def_id(node_id)), } } diff --git a/src/librustc_trans/symbol_map.rs b/src/librustc_trans/symbol_map.rs index 880c65937e308..fd07d569155d4 100644 --- a/src/librustc_trans/symbol_map.rs +++ b/src/librustc_trans/symbol_map.rs @@ -99,7 +99,10 @@ impl<'tcx> SymbolMap<'tcx> { TransItem::Fn(Instance { def, .. }) => { tcx.hir.as_local_node_id(def) } - TransItem::Static(node_id) => Some(node_id), + TransItem::Static(node_id) | + TransItem::GlobalAsm(node_id) => { + Some(node_id) + } TransItem::DropGlue(_) => None, }.map(|node_id| { tcx.hir.span(node_id) diff --git a/src/librustc_trans/trans_item.rs b/src/librustc_trans/trans_item.rs index d19f04b9554fb..2786f0a57b701 100644 --- a/src/librustc_trans/trans_item.rs +++ b/src/librustc_trans/trans_item.rs @@ -14,6 +14,7 @@ //! item-path. This is used for unit testing the code that generates //! paths etc in all kinds of annoying scenarios. +use asm; use attributes; use base; use consts; @@ -42,7 +43,8 @@ use std::iter; pub enum TransItem<'tcx> { DropGlue(DropGlueKind<'tcx>), Fn(Instance<'tcx>), - Static(NodeId) + Static(NodeId), + GlobalAsm(NodeId), } /// Describes how a translation item will be instantiated in object files. @@ -93,6 +95,14 @@ impl<'a, 'tcx> TransItem<'tcx> { span_bug!(item.span, "Mismatch between hir::Item type and TransItem type") } } + TransItem::GlobalAsm(node_id) => { + let item = ccx.tcx().hir.expect_item(node_id); + if let hir::ItemGlobalAsm(ref ga) = item.node { + asm::trans_global_asm(ccx, ga); + } else { + span_bug!(item.span, "Mismatch between hir::Item type and TransItem type") + } + } TransItem::Fn(instance) => { let _task = ccx.tcx().dep_graph.in_task( DepNode::TransCrateItem(instance.def)); // (*) @@ -133,6 +143,7 @@ impl<'a, 'tcx> TransItem<'tcx> { TransItem::DropGlue(dg) => { TransItem::predefine_drop_glue(ccx, dg, linkage, &symbol_name); } + TransItem::GlobalAsm(..) => {} } debug!("END PREDEFINING '{} ({})' in cgu {}", @@ -235,6 +246,10 @@ impl<'a, 'tcx> TransItem<'tcx> { }; symbol_names::exported_name_from_type_and_prefix(scx, dg.ty(), prefix) } + TransItem::GlobalAsm(node_id) => { + let def_id = scx.tcx().hir.local_def_id(node_id); + format!("global_asm_{:?}", def_id) + } } } @@ -242,7 +257,8 @@ impl<'a, 'tcx> TransItem<'tcx> { match *self { TransItem::Fn(ref instance) => !instance.def.is_local(), TransItem::DropGlue(..) | - TransItem::Static(..) => false, + TransItem::Static(..) | + TransItem::GlobalAsm(..) => false, } } @@ -261,6 +277,7 @@ impl<'a, 'tcx> TransItem<'tcx> { } TransItem::DropGlue(..) => InstantiationMode::LocalCopy, TransItem::Static(..) => InstantiationMode::GloballyShared, + TransItem::GlobalAsm(..) => InstantiationMode::GloballyShared, } } @@ -270,7 +287,8 @@ impl<'a, 'tcx> TransItem<'tcx> { instance.substs.types().next().is_some() } TransItem::DropGlue(..) | - TransItem::Static(..) => false, + TransItem::Static(..) | + TransItem::GlobalAsm(..) => false, } } @@ -278,7 +296,7 @@ impl<'a, 'tcx> TransItem<'tcx> { let def_id = match *self { TransItem::Fn(ref instance) => instance.def, TransItem::Static(node_id) => tcx.hir.local_def_id(node_id), - TransItem::DropGlue(..) => return None, + TransItem::DropGlue(..) | TransItem::GlobalAsm(..) => return None, }; let attributes = tcx.get_attrs(def_id); @@ -320,6 +338,9 @@ impl<'a, 'tcx> TransItem<'tcx> { let instance = Instance::new(def_id, tcx.intern_substs(&[])); to_string_internal(tcx, "static ", instance) }, + TransItem::GlobalAsm(..) => { + "global_asm".to_string() + } }; fn to_string_internal<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, @@ -351,6 +372,9 @@ impl<'a, 'tcx> TransItem<'tcx> { TransItem::Static(id) => { format!("Static({:?})", id) } + TransItem::GlobalAsm(id) => { + format!("GlobalAsm({:?})", id) + } } } }