From: Michael Woerister Date: Tue, 10 May 2016 03:56:49 +0000 (-0400) Subject: Make drop-glue translation collector-driven. X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=87c1c87dd7389466333a976d9c536c083c311443;p=rust.git Make drop-glue translation collector-driven. --- diff --git a/src/librustc_trans/abi.rs b/src/librustc_trans/abi.rs index df3d2d149b9..6c2a09f8060 100644 --- a/src/librustc_trans/abi.rs +++ b/src/librustc_trans/abi.rs @@ -229,6 +229,7 @@ pub fn store_fn_arg(&self, bcx: &BlockAndBuilder, idx: &mut usize, dst: ValueRef /// /// I will do my best to describe this structure, but these /// comments are reverse-engineered and may be inaccurate. -NDM +#[derive(Clone)] pub struct FnType { /// The LLVM types of each argument. pub args: Vec, diff --git a/src/librustc_trans/back/symbol_names.rs b/src/librustc_trans/back/symbol_names.rs index 170c8f75b50..ebb6e0baf20 100644 --- a/src/librustc_trans/back/symbol_names.rs +++ b/src/librustc_trans/back/symbol_names.rs @@ -304,6 +304,19 @@ fn push(&mut self, text: &str) { } } +pub fn exported_name_from_type_and_prefix<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>, + t: ty::Ty<'tcx>, + prefix: &str) + -> String { + let empty_def_path = DefPath { + data: vec![], + krate: cstore::LOCAL_CRATE, + }; + let hash = get_symbol_hash(scx, &empty_def_path, t, &[]); + let path = [token::intern_and_get_ident(prefix)]; + mangle(path.iter().cloned(), Some(&hash[..])) +} + /// Only symbols that are invisible outside their compilation unit should use a /// name generated by this function. pub fn internal_name_from_type_and_suffix<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 3ee53a4d95e..5dc319aa5f9 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -2182,52 +2182,6 @@ pub fn llvm_linkage_by_name(name: &str) -> Option { } } -/// Set the appropriate linkage for an LLVM `ValueRef` (function or global). -/// If the `llval` is the direct translation of a specific Rust item, `id` -/// should be set to the `NodeId` of that item. (This mapping should be -/// 1-to-1, so monomorphizations and drop/visit glue should have `id` set to -/// `None`.) -pub fn update_linkage(ccx: &CrateContext, - llval: ValueRef, - id: Option) { - if let Some(id) = id { - let item = ccx.tcx().map.get(id); - if let hir_map::NodeItem(i) = item { - if let Some(name) = attr::first_attr_value_str_by_name(&i.attrs, "linkage") { - if let Some(linkage) = llvm_linkage_by_name(&name) { - llvm::SetLinkage(llval, linkage); - } else { - ccx.sess().span_fatal(i.span, "invalid linkage specified"); - } - return; - } - } - } - - let (is_reachable, is_generic) = if let Some(id) = id { - (ccx.reachable().contains(&id), false) - } else { - (false, true) - }; - - // We need external linkage for items reachable from other translation units, this include - // other codegen units in case of parallel compilations. - if is_reachable || ccx.sess().opts.cg.codegen_units > 1 { - if is_generic { - // This only happens with multiple codegen units, in which case we need to use weak_odr - // linkage because other crates might expose the same symbol. We cannot use - // linkonce_odr here because the symbol might then get dropped before the other codegen - // units get to link it. - llvm::SetUniqueComdat(ccx.llmod(), llval); - llvm::SetLinkage(llval, llvm::WeakODRLinkage); - } else { - llvm::SetLinkage(llval, llvm::ExternalLinkage); - } - } else { - llvm::SetLinkage(llval, llvm::InternalLinkage); - } -} - pub fn set_link_section(ccx: &CrateContext, llval: ValueRef, attrs: &[ast::Attribute]) { @@ -2673,24 +2627,8 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // ... and now that we have everything pre-defined, fill out those definitions. for ccx in crate_context_list.iter() { - for (&trans_item, _) in &ccx.codegen_unit().items { - match trans_item { - TransItem::Static(node_id) => { - let item = ccx.tcx().map.expect_item(node_id); - if let hir::ItemStatic(_, m, ref expr) = item.node { - match consts::trans_static(&ccx, m, expr, item.id, &item.attrs) { - Ok(_) => { /* Cool, everything's alright. */ }, - Err(err) => ccx.tcx().sess.span_fatal(expr.span, &err.description()), - }; - } else { - span_bug!(item.span, "Mismatch between hir::Item type and TransItem type") - } - } - TransItem::Fn(instance) => { - trans_instance(&ccx, instance); - } - _ => { } - } + for (trans_item, _) in &ccx.codegen_unit().items { + trans_item.define(&ccx); } } @@ -2927,7 +2865,7 @@ fn collect_and_partition_translation_items<'a, 'tcx>(scx: &SharedCrateContext<'a let mut item_keys: Vec<_> = items .iter() .map(|i| { - let mut output = i.to_string(scx); + let mut output = i.to_string(scx.tcx()); output.push_str(" @@"); let mut empty = Vec::new(); let mut cgus = item_to_cgus.get_mut(i).unwrap_or(&mut empty); diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs index 8cb9fd23e49..aff50e5e1f4 100644 --- a/src/librustc_trans/collector.rs +++ b/src/librustc_trans/collector.rs @@ -325,7 +325,7 @@ fn collect_items_rec<'a, 'tcx: 'a>(scx: &SharedCrateContext<'a, 'tcx>, // We've been here already, no need to search again. return; } - debug!("BEGIN collect_items_rec({})", starting_point.to_string(scx)); + debug!("BEGIN collect_items_rec({})", starting_point.to_string(scx.tcx())); let mut neighbors = Vec::new(); let recursion_depth_reset; @@ -396,7 +396,7 @@ fn collect_items_rec<'a, 'tcx: 'a>(scx: &SharedCrateContext<'a, 'tcx>, recursion_depths.insert(def_id, depth); } - debug!("END collect_items_rec({})", starting_point.to_string(scx)); + debug!("END collect_items_rec({})", starting_point.to_string(scx.tcx())); } fn record_inlining_canditates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, @@ -637,7 +637,8 @@ fn visit_terminator_kind(&mut self, let operand_ty = monomorphize::apply_param_substs(tcx, self.param_substs, &mt.ty); - self.output.push(TransItem::DropGlue(DropGlueKind::Ty(operand_ty))); + let ty = glue::get_drop_glue_type(tcx, operand_ty); + self.output.push(TransItem::DropGlue(DropGlueKind::Ty(ty))); } else { bug!("Has the drop_in_place() intrinsic's signature changed?") } @@ -1271,7 +1272,7 @@ fn hash(t: &T) -> u64 { let mut item_keys = FnvHashMap(); for (item, item_state) in trans_items.iter() { - let k = item.to_string(scx); + let k = item.to_string(scx.tcx()); if item_keys.contains_key(&k) { let prev: (TransItem, TransItemState) = item_keys[&k]; @@ -1299,7 +1300,7 @@ fn hash(t: &T) -> u64 { let mut generated = FnvHashSet(); for (item, item_state) in trans_items.iter() { - let item_key = item.to_string(scx); + let item_key = item.to_string(scx.tcx()); match *item_state { TransItemState::PredictedAndGenerated => { diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs index bfcb1ae33b3..7f6e8fa035a 100644 --- a/src/librustc_trans/context.rs +++ b/src/librustc_trans/context.rs @@ -36,7 +36,7 @@ use session::config::NoDebugInfo; use session::Session; use util::sha2::Sha256; -use util::nodemap::{NodeMap, NodeSet, DefIdMap, FnvHashMap, FnvHashSet}; +use util::nodemap::{NodeMap, NodeSet, DefIdMap, FnvHashMap}; use std::ffi::{CStr, CString}; use std::cell::{Cell, RefCell}; @@ -46,6 +46,7 @@ use std::str; use syntax::ast; use syntax::parse::token::InternedString; +use abi::FnType; pub struct Stats { pub n_glues_created: Cell, @@ -80,8 +81,6 @@ pub struct SharedCrateContext<'a, 'tcx: 'a> { mir_map: &'a MirMap<'tcx>, mir_cache: RefCell>>>, - available_monomorphizations: RefCell>, - available_drop_glues: RefCell, String>>, use_dll_storage_attrs: bool, translation_items: RefCell, TransItemState>>, @@ -99,7 +98,7 @@ pub struct LocalCrateContext<'tcx> { codegen_unit: CodegenUnit<'tcx>, needs_unwind_cleanup_cache: RefCell, bool>>, fn_pointer_shims: RefCell, ValueRef>>, - drop_glues: RefCell, ValueRef>>, + drop_glues: RefCell, (ValueRef, FnType)>>, /// Track mapping of external ids to local items imported for inlining external: RefCell>>, /// Backwards version of the `external` map (inlined items to where they @@ -413,8 +412,6 @@ pub fn new(tcx: TyCtxt<'b, 'tcx, 'tcx>, }, check_overflow: check_overflow, check_drop_flag_for_sanity: check_drop_flag_for_sanity, - available_monomorphizations: RefCell::new(FnvHashSet()), - available_drop_glues: RefCell::new(FnvHashMap()), use_dll_storage_attrs: use_dll_storage_attrs, translation_items: RefCell::new(FnvHashMap()), trait_cache: RefCell::new(DepTrackingMap::new(tcx.dep_graph.clone())), @@ -730,7 +727,8 @@ pub fn fn_pointer_shims(&self) -> &RefCell, ValueRef>> { &self.local().fn_pointer_shims } - pub fn drop_glues<'a>(&'a self) -> &'a RefCell, ValueRef>> { + pub fn drop_glues<'a>(&'a self) + -> &'a RefCell, (ValueRef, FnType)>> { &self.local().drop_glues } @@ -816,14 +814,6 @@ pub fn stats<'a>(&'a self) -> &'a Stats { &self.shared.stats } - pub fn available_monomorphizations<'a>(&'a self) -> &'a RefCell> { - &self.shared.available_monomorphizations - } - - pub fn available_drop_glues(&self) -> &RefCell, String>> { - &self.shared.available_drop_glues - } - pub fn int_type(&self) -> Type { self.local().int_type } diff --git a/src/librustc_trans/declare.rs b/src/librustc_trans/declare.rs index e6db695943b..2746d3fb6b0 100644 --- a/src/librustc_trans/declare.rs +++ b/src/librustc_trans/declare.rs @@ -138,24 +138,34 @@ pub fn define_global(ccx: &CrateContext, name: &str, ty: Type) -> Option(ccx: &CrateContext<'a, 'tcx>, - name: &str, - fn_type: ty::Ty<'tcx>) -> ValueRef { +pub fn define_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, + name: &str, + fn_type: ty::Ty<'tcx>) -> ValueRef { if get_defined_value(ccx, name).is_some() { ccx.sess().fatal(&format!("symbol `{}` already defined", name)) } else { - let llfn = declare_fn(ccx, name, fn_type); - llvm::SetLinkage(llfn, llvm::InternalLinkage); - llfn + declare_fn(ccx, name, fn_type) } } +/// Declare a Rust function with an intention to define it. +/// +/// Use this function when you intend to define a function. This function will +/// return panic if the name already has a definition associated with it. This +/// can happen with #[no_mangle] or #[export_name], for example. +pub fn define_internal_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, + name: &str, + fn_type: ty::Ty<'tcx>) -> ValueRef { + let llfn = define_fn(ccx, name, fn_type); + llvm::SetLinkage(llfn, llvm::InternalLinkage); + llfn +} + /// Get declared value by name. pub fn get_declared_value(ccx: &CrateContext, name: &str) -> Option { diff --git a/src/librustc_trans/glue.rs b/src/librustc_trans/glue.rs index e4519ff82a0..30eb71a9006 100644 --- a/src/librustc_trans/glue.rs +++ b/src/librustc_trans/glue.rs @@ -14,15 +14,12 @@ use std; -use attributes; -use back::symbol_names; use llvm; use llvm::{ValueRef, get_param}; use middle::lang_items::ExchangeFreeFnLangItem; use rustc::ty::subst::{Substs}; use rustc::traits; use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; -use abi::{Abi, FnType}; use adt; use adt::GetDtorType; // for tcx.dtor_type() use base::*; @@ -33,7 +30,6 @@ use collector; use common::*; use debuginfo::DebugLoc; -use declare; use expr; use machine::*; use monomorphize; @@ -236,48 +232,21 @@ pub fn map_ty(&self, mut f: F) -> DropGlueKind<'tcx> where F: FnMut(Ty<'tcx>) fn get_drop_glue_core<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, g: DropGlueKind<'tcx>) -> ValueRef { - debug!("make drop glue for {:?}", g); let g = g.map_ty(|t| get_drop_glue_type(ccx.tcx(), t)); - debug!("drop glue type {:?}", g); match ccx.drop_glues().borrow().get(&g) { - Some(&glue) => return glue, - _ => { } + Some(&(glue, _)) => glue, + None => { bug!("Could not find drop glue for {:?} -- {} -- {}", + g, + TransItem::DropGlue(g).to_raw_string(), + ccx.codegen_unit().name) } } - let t = g.ty(); +} +pub fn implement_drop_glue<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, + g: DropGlueKind<'tcx>) { let tcx = ccx.tcx(); - let sig = ty::FnSig { - inputs: vec![tcx.mk_mut_ptr(tcx.types.i8)], - output: ty::FnOutput::FnConverging(tcx.mk_nil()), - variadic: false, - }; - // Create a FnType for fn(*mut i8) and substitute the real type in - // later - that prevents FnType from splitting fat pointers up. - let mut fn_ty = FnType::new(ccx, Abi::Rust, &sig, &[]); - fn_ty.args[0].original_ty = type_of(ccx, t).ptr_to(); - let llfnty = fn_ty.llvm_type(ccx); - - // To avoid infinite recursion, don't `make_drop_glue` until after we've - // added the entry to the `drop_glues` cache. - if let Some(old_sym) = ccx.available_drop_glues().borrow().get(&g) { - let llfn = declare::declare_cfn(ccx, &old_sym, llfnty); - ccx.drop_glues().borrow_mut().insert(g, llfn); - return llfn; - }; - - let suffix = match g { - DropGlueKind::Ty(_) => "drop", - DropGlueKind::TyContents(_) => "drop_contents", - }; - - let fn_nm = symbol_names::internal_name_from_type_and_suffix(ccx, t, suffix); - assert!(declare::get_defined_value(ccx, &fn_nm).is_none()); - let llfn = declare::declare_cfn(ccx, &fn_nm, llfnty); - attributes::set_frame_pointer_elimination(ccx, llfn); - ccx.available_drop_glues().borrow_mut().insert(g, fn_nm); - ccx.drop_glues().borrow_mut().insert(g, llfn); - - let _s = StatRecorder::new(ccx, format!("drop {:?}", t)); + assert_eq!(g.ty(), get_drop_glue_type(tcx, g.ty())); + let (llfn, fn_ty) = ccx.drop_glues().borrow().get(&g).unwrap().clone(); let (arena, fcx): (TypedArena<_>, FunctionContext); arena = TypedArena::new(); @@ -285,8 +254,6 @@ fn get_drop_glue_core<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, let bcx = fcx.init(false, None); - update_linkage(ccx, llfn, None); - ccx.stats().n_glues_created.set(ccx.stats().n_glues_created.get() + 1); // All glue functions take values passed *by alias*; this is a // requirement since in many contexts glue is invoked indirectly and @@ -298,10 +265,9 @@ fn get_drop_glue_core<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, let bcx = make_drop_glue(bcx, get_param(llfn, 0), g); fcx.finish(bcx, DebugLoc::None); - - llfn } + fn trans_struct_drop_flag<'blk, 'tcx>(mut bcx: Block<'blk, 'tcx>, t: Ty<'tcx>, struct_data: ValueRef) diff --git a/src/librustc_trans/partitioning.rs b/src/librustc_trans/partitioning.rs index cd08fe68f0c..a0360a8ed22 100644 --- a/src/librustc_trans/partitioning.rs +++ b/src/librustc_trans/partitioning.rs @@ -165,10 +165,14 @@ pub fn partition<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, trans_items, reachable); + debug_dump(tcx, "INITIAL PARTITONING:", initial_partitioning.codegen_units.iter()); + // If the partitioning should produce a fixed count of codegen units, merge // until that count is reached. if let PartitioningStrategy::FixedUnitCount(count) = strategy { merge_codegen_units(&mut initial_partitioning, count, &tcx.crate_name[..]); + + debug_dump(tcx, "POST MERGING:", initial_partitioning.codegen_units.iter()); } // In the next step, we use the inlining map to determine which addtional @@ -177,6 +181,9 @@ pub fn partition<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // local functions the definition of which is marked with #[inline]. let post_inlining = place_inlined_translation_items(initial_partitioning, inlining_map); + + debug_dump(tcx, "POST INLINING:", post_inlining.0.iter()); + post_inlining.0 } @@ -484,3 +491,23 @@ fn numbered_codegen_unit_name(crate_name: &str, index: usize) -> InternedString NUMBERED_CODEGEN_UNIT_MARKER, index)[..]) } + +fn debug_dump<'a, 'b, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, + label: &str, + cgus: I) + where I: Iterator>, + 'tcx: 'a + 'b +{ + if cfg!(debug_assertions) { + debug!("{}", label); + for cgu in cgus { + debug!("CodegenUnit {}:", cgu.name); + + for (trans_item, linkage) in &cgu.items { + debug!(" - {} [{:?}]", trans_item.to_string(tcx), linkage); + } + + debug!(""); + } + } +} diff --git a/src/librustc_trans/trans_item.rs b/src/librustc_trans/trans_item.rs index ae6e095d142..a07deda2b1e 100644 --- a/src/librustc_trans/trans_item.rs +++ b/src/librustc_trans/trans_item.rs @@ -16,7 +16,8 @@ use attributes; use base; -use context::{SharedCrateContext, CrateContext}; +use consts; +use context::CrateContext; use declare; use glue::DropGlueKind; use llvm; @@ -32,7 +33,9 @@ use syntax::{attr,errors}; use syntax::parse::token; use type_of; - +use glue; +use abi::{Abi, FnType}; +use back::symbol_names; #[derive(PartialEq, Eq, Clone, Copy, Debug)] pub enum TransItem<'tcx> { @@ -64,9 +67,47 @@ fn hash(&self, s: &mut H) { impl<'a, 'tcx> TransItem<'tcx> { + pub fn define(&self, ccx: &CrateContext<'a, 'tcx>) { + + debug!("BEGIN IMPLEMENTING '{} ({})' in cgu {}", + self.to_string(ccx.tcx()), + self.to_raw_string(), + ccx.codegen_unit().name); + + match *self { + TransItem::Static(node_id) => { + let item = ccx.tcx().map.expect_item(node_id); + if let hir::ItemStatic(_, m, ref expr) = item.node { + match consts::trans_static(&ccx, m, expr, item.id, &item.attrs) { + Ok(_) => { /* Cool, everything's alright. */ }, + Err(err) => ccx.tcx().sess.span_fatal(expr.span, &err.description()), + }; + } else { + span_bug!(item.span, "Mismatch between hir::Item type and TransItem type") + } + } + TransItem::Fn(instance) => { + base::trans_instance(&ccx, instance); + } + TransItem::DropGlue(dg) => { + glue::implement_drop_glue(&ccx, dg); + } + } + + debug!("END IMPLEMENTING '{} ({})' in cgu {}", + self.to_string(ccx.tcx()), + self.to_raw_string(), + ccx.codegen_unit().name); + } + pub fn predefine(&self, ccx: &CrateContext<'a, 'tcx>, linkage: llvm::Linkage) { + debug!("BEGIN PREDEFINING '{} ({})' in cgu {}", + self.to_string(ccx.tcx()), + self.to_raw_string(), + ccx.codegen_unit().name); + match *self { TransItem::Static(node_id) => { TransItem::predefine_static(ccx, node_id, linkage); @@ -74,10 +115,15 @@ pub fn predefine(&self, TransItem::Fn(instance) => { TransItem::predefine_fn(ccx, instance, linkage); } - _ => { - // Not yet implemented + TransItem::DropGlue(dg) => { + TransItem::predefine_drop_glue(ccx, dg, linkage); } } + + debug!("END PREDEFINING '{} ({})' in cgu {}", + self.to_string(ccx.tcx()), + self.to_raw_string(), + ccx.codegen_unit().name); } fn predefine_static(ccx: &CrateContext<'a, 'tcx>, @@ -93,7 +139,7 @@ fn predefine_static(ccx: &CrateContext<'a, 'tcx>, }) => { let instance = Instance::mono(ccx.shared(), def_id); let sym = instance.symbol_name(ccx.shared()); - debug!("making {}", sym); + debug!("symbol {}", sym); let g = declare::define_global(ccx, &sym, llty).unwrap_or_else(|| { ccx.sess().span_fatal(span, @@ -110,8 +156,6 @@ fn predefine_static(ccx: &CrateContext<'a, 'tcx>, fn predefine_fn(ccx: &CrateContext<'a, 'tcx>, instance: Instance<'tcx>, linkage: llvm::Linkage) { - let unit = ccx.codegen_unit(); - debug!("predefine_fn[cg={}](instance={:?})", &unit.name[..], instance); assert!(!instance.substs.types.needs_infer() && !instance.substs.types.has_param_types()); @@ -143,10 +187,11 @@ fn predefine_fn(ccx: &CrateContext<'a, 'tcx>, ref attrs, node: hir::ImplItemKind::Method(..), .. }) => { let symbol = instance.symbol_name(ccx.shared()); - let lldecl = declare::declare_fn(ccx, &symbol, mono_ty); + debug!("symbol {}", symbol); - attributes::from_fn_attrs(ccx, attrs, lldecl); + let lldecl = declare::declare_fn(ccx, &symbol, mono_ty); llvm::SetLinkage(lldecl, linkage); + attributes::from_fn_attrs(ccx, attrs, lldecl); base::set_link_section(ccx, lldecl, attrs); ccx.instances().borrow_mut().insert(instance, lldecl); @@ -156,6 +201,39 @@ fn predefine_fn(ccx: &CrateContext<'a, 'tcx>, } + fn predefine_drop_glue(ccx: &CrateContext<'a, 'tcx>, + dg: glue::DropGlueKind<'tcx>, + linkage: llvm::Linkage) { + let tcx = ccx.tcx(); + assert_eq!(dg.ty(), glue::get_drop_glue_type(tcx, dg.ty())); + let t = dg.ty(); + + let sig = ty::FnSig { + inputs: vec![tcx.mk_mut_ptr(tcx.types.i8)], + output: ty::FnOutput::FnConverging(tcx.mk_nil()), + variadic: false, + }; + + // Create a FnType for fn(*mut i8) and substitute the real type in + // later - that prevents FnType from splitting fat pointers up. + let mut fn_ty = FnType::new(ccx, Abi::Rust, &sig, &[]); + fn_ty.args[0].original_ty = type_of::type_of(ccx, t).ptr_to(); + let llfnty = fn_ty.llvm_type(ccx); + + let prefix = match dg { + DropGlueKind::Ty(_) => "drop", + DropGlueKind::TyContents(_) => "drop_contents", + }; + + let symbol = + symbol_names::exported_name_from_type_and_prefix(ccx.shared(), t, prefix); + debug!(" symbol: {}", symbol); + assert!(declare::get_defined_value(ccx, &symbol).is_none()); + let llfn = declare::declare_cfn(ccx, &symbol, llfnty); + attributes::set_frame_pointer_elimination(ccx, llfn); + llvm::SetLinkage(llfn, linkage); + ccx.drop_glues().borrow_mut().insert(dg, (llfn, fn_ty)); + } pub fn requests_inline(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> bool { match *self { @@ -216,8 +294,7 @@ pub fn explicit_linkage(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Option) -> String { - let tcx = scx.tcx(); + pub fn to_string(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> String { let hir_map = &tcx.map; return match *self { @@ -235,7 +312,8 @@ pub fn to_string(&self, scx: &SharedCrateContext<'a, 'tcx>) -> String { }, TransItem::Static(node_id) => { let def_id = hir_map.local_def_id(node_id); - let instance = Instance::mono(scx, def_id); + let instance = Instance::new(def_id, + tcx.mk_substs(subst::Substs::empty())); to_string_internal(tcx, "static ", instance) }, }; @@ -254,7 +332,11 @@ fn to_string_internal<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, pub fn to_raw_string(&self) -> String { match *self { TransItem::DropGlue(dg) => { - format!("DropGlue({})", dg.ty() as *const _ as usize) + let prefix = match dg { + DropGlueKind::Ty(_) => "Ty", + DropGlueKind::TyContents(_) => "TyContents", + }; + format!("DropGlue({}: {})", prefix, dg.ty() as *const _ as usize) } TransItem::Fn(instance) => { format!("Fn({:?}, {})",