Avoid redundant work for drop-glue translation items in trans::collector
This commit is contained in:
parent
9e969808e2
commit
4d074b8c4c
@ -350,14 +350,14 @@ fn collect_items_rec<'a, 'tcx: 'a>(ccx: &CrateContext<'a, 'tcx>,
|
|||||||
let recursion_depth_reset;
|
let recursion_depth_reset;
|
||||||
|
|
||||||
match starting_point {
|
match starting_point {
|
||||||
TransItem::DropGlue(_) |
|
TransItem::DropGlue(t) => {
|
||||||
|
find_drop_glue_neighbors(ccx, t, &mut neighbors);
|
||||||
|
recursion_depth_reset = None;
|
||||||
|
}
|
||||||
TransItem::Static(_) => {
|
TransItem::Static(_) => {
|
||||||
recursion_depth_reset = None;
|
recursion_depth_reset = None;
|
||||||
}
|
}
|
||||||
TransItem::Fn {
|
TransItem::Fn { def_id, substs: ref param_substs } => {
|
||||||
def_id,
|
|
||||||
substs: ref param_substs
|
|
||||||
} => {
|
|
||||||
// Keep track of the monomorphization recursion depth
|
// Keep track of the monomorphization recursion depth
|
||||||
recursion_depth_reset = Some(check_recursion_limit(ccx,
|
recursion_depth_reset = Some(check_recursion_limit(ccx,
|
||||||
def_id,
|
def_id,
|
||||||
@ -531,11 +531,8 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
|
|||||||
self.param_substs,
|
self.param_substs,
|
||||||
&ty);
|
&ty);
|
||||||
let ty = self.ccx.tcx().erase_regions(&ty);
|
let ty = self.ccx.tcx().erase_regions(&ty);
|
||||||
|
let ty = glue::get_drop_glue_type(self.ccx, ty);
|
||||||
create_drop_glue_trans_items(self.ccx,
|
self.output.push(TransItem::DropGlue(ty));
|
||||||
ty,
|
|
||||||
self.param_substs,
|
|
||||||
&mut self.output);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.super_lvalue(lvalue, context);
|
self.super_lvalue(lvalue, context);
|
||||||
@ -636,145 +633,124 @@ fn can_have_local_instance<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
|||||||
def_id.is_local() || ccx.sess().cstore.is_item_mir_available(def_id)
|
def_id.is_local() || ccx.sess().cstore.is_item_mir_available(def_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_drop_glue_trans_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
fn find_drop_glue_neighbors<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
|
||||||
mono_ty: ty::Ty<'tcx>,
|
ty: ty::Ty<'tcx>,
|
||||||
param_substs: &'tcx Substs<'tcx>,
|
output: &mut Vec<TransItem<'tcx>>)
|
||||||
output: &mut Vec<TransItem<'tcx>>)
|
|
||||||
{
|
{
|
||||||
visit_types_of_owned_components(ccx,
|
debug!("find_drop_glue_neighbors: {}", type_to_string(ccx, ty));
|
||||||
mono_ty,
|
|
||||||
&mut FnvHashSet(),
|
|
||||||
&mut |ty| {
|
|
||||||
debug!("create_drop_glue_trans_items: {}", type_to_string(ccx, ty));
|
|
||||||
// Add a translation item for the drop glue, if even this type does not
|
|
||||||
// need to be dropped (in which case it has been mapped to i8)
|
|
||||||
output.push(TransItem::DropGlue(ty));
|
|
||||||
|
|
||||||
if glue::type_needs_drop(ccx.tcx(), ty) {
|
// Make sure the exchange_free_fn() lang-item gets translated if
|
||||||
|
// there is a boxed value.
|
||||||
|
if let ty::TyBox(_) = ty.sty {
|
||||||
|
let exchange_free_fn_def_id = ccx.tcx()
|
||||||
|
.lang_items
|
||||||
|
.require(ExchangeFreeFnLangItem)
|
||||||
|
.expect("Could not find ExchangeFreeFnLangItem");
|
||||||
|
|
||||||
// Make sure the exchange_free_fn() lang-item gets translated if
|
assert!(can_have_local_instance(ccx, exchange_free_fn_def_id));
|
||||||
// there is a boxed value.
|
let exchange_free_fn_trans_item =
|
||||||
if let ty::TyBox(_) = ty.sty {
|
create_fn_trans_item(ccx,
|
||||||
|
exchange_free_fn_def_id,
|
||||||
|
&Substs::trans_empty(),
|
||||||
|
&Substs::trans_empty());
|
||||||
|
|
||||||
let exchange_free_fn_def_id = ccx.tcx()
|
output.push(exchange_free_fn_trans_item);
|
||||||
.lang_items
|
}
|
||||||
.require(ExchangeFreeFnLangItem)
|
|
||||||
.expect("Could not find ExchangeFreeFnLangItem");
|
|
||||||
|
|
||||||
assert!(can_have_local_instance(ccx, exchange_free_fn_def_id));
|
// If the type implements Drop, also add a translation item for the
|
||||||
let exchange_free_fn_trans_item =
|
// monomorphized Drop::drop() implementation.
|
||||||
create_fn_trans_item(ccx,
|
let destructor_did = match ty.sty {
|
||||||
exchange_free_fn_def_id,
|
ty::TyStruct(def, _) |
|
||||||
&Substs::trans_empty(),
|
ty::TyEnum(def, _) => def.destructor(),
|
||||||
param_substs);
|
_ => None
|
||||||
|
};
|
||||||
|
|
||||||
output.push(exchange_free_fn_trans_item);
|
if let Some(destructor_did) = destructor_did {
|
||||||
}
|
use rustc::middle::ty::ToPolyTraitRef;
|
||||||
|
|
||||||
// If the type implements Drop, also add a translation item for the
|
let drop_trait_def_id = ccx.tcx()
|
||||||
// monomorphized Drop::drop() implementation.
|
.lang_items
|
||||||
let destructor_did = match ty.sty {
|
.drop_trait()
|
||||||
ty::TyStruct(def, _) |
|
.unwrap();
|
||||||
ty::TyEnum(def, _) => def.destructor(),
|
|
||||||
_ => None
|
|
||||||
};
|
|
||||||
|
|
||||||
if let Some(destructor_did) = destructor_did {
|
let self_type_substs = ccx.tcx().mk_substs(
|
||||||
use rustc::middle::ty::ToPolyTraitRef;
|
Substs::trans_empty().with_self_ty(ty));
|
||||||
|
|
||||||
let drop_trait_def_id = ccx.tcx()
|
let trait_ref = ty::TraitRef {
|
||||||
.lang_items
|
def_id: drop_trait_def_id,
|
||||||
.drop_trait()
|
substs: self_type_substs,
|
||||||
.unwrap();
|
}.to_poly_trait_ref();
|
||||||
|
|
||||||
let self_type_substs = ccx.tcx().mk_substs(
|
let substs = match fulfill_obligation(ccx, DUMMY_SP, trait_ref) {
|
||||||
Substs::trans_empty().with_self_ty(ty));
|
traits::VtableImpl(data) => data.substs,
|
||||||
|
_ => unreachable!()
|
||||||
|
};
|
||||||
|
|
||||||
let trait_ref = ty::TraitRef {
|
if can_have_local_instance(ccx, destructor_did) {
|
||||||
def_id: drop_trait_def_id,
|
let trans_item = create_fn_trans_item(ccx,
|
||||||
substs: self_type_substs,
|
destructor_did,
|
||||||
}.to_poly_trait_ref();
|
ccx.tcx().mk_substs(substs),
|
||||||
|
&Substs::trans_empty());
|
||||||
let substs = match fulfill_obligation(ccx, DUMMY_SP, trait_ref) {
|
output.push(trans_item);
|
||||||
traits::VtableImpl(data) => data.substs,
|
|
||||||
_ => unreachable!()
|
|
||||||
};
|
|
||||||
|
|
||||||
if can_have_local_instance(ccx, destructor_did) {
|
|
||||||
let trans_item = create_fn_trans_item(ccx,
|
|
||||||
destructor_did,
|
|
||||||
ccx.tcx().mk_substs(substs),
|
|
||||||
param_substs);
|
|
||||||
output.push(trans_item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
fn visit_types_of_owned_components<'a, 'tcx, F>(ccx: &CrateContext<'a, 'tcx>,
|
// Finally add the types of nested values
|
||||||
ty: ty::Ty<'tcx>,
|
match ty.sty {
|
||||||
visited: &mut FnvHashSet<ty::Ty<'tcx>>,
|
ty::TyBool |
|
||||||
mut f: &mut F)
|
ty::TyChar |
|
||||||
where F: FnMut(ty::Ty<'tcx>) -> bool
|
ty::TyInt(_) |
|
||||||
{
|
ty::TyUint(_) |
|
||||||
let ty = glue::get_drop_glue_type(ccx, ty);
|
ty::TyStr |
|
||||||
|
ty::TyFloat(_) |
|
||||||
if !visited.insert(ty) {
|
ty::TyRawPtr(_) |
|
||||||
return;
|
ty::TyRef(..) |
|
||||||
|
ty::TyBareFn(..) |
|
||||||
|
ty::TySlice(_) |
|
||||||
|
ty::TyTrait(_) => {
|
||||||
|
/* nothing to do */
|
||||||
}
|
}
|
||||||
|
ty::TyStruct(ref adt_def, substs) |
|
||||||
|
ty::TyEnum(ref adt_def, substs) => {
|
||||||
|
for field in adt_def.all_fields() {
|
||||||
|
let field_type = monomorphize::apply_param_substs(ccx.tcx(),
|
||||||
|
substs,
|
||||||
|
&field.unsubst_ty());
|
||||||
|
let field_type = glue::get_drop_glue_type(ccx, field_type);
|
||||||
|
|
||||||
if !f(ty) {
|
if glue::type_needs_drop(ccx.tcx(), field_type) {
|
||||||
// Don't recurse further
|
output.push(TransItem::DropGlue(field_type));
|
||||||
return;
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
ty::TyClosure(_, ref substs) => {
|
||||||
match ty.sty {
|
for upvar_ty in &substs.upvar_tys {
|
||||||
ty::TyBool |
|
let upvar_ty = glue::get_drop_glue_type(ccx, upvar_ty);
|
||||||
ty::TyChar |
|
if glue::type_needs_drop(ccx.tcx(), upvar_ty) {
|
||||||
ty::TyInt(_) |
|
output.push(TransItem::DropGlue(upvar_ty));
|
||||||
ty::TyUint(_) |
|
|
||||||
ty::TyStr |
|
|
||||||
ty::TyFloat(_) |
|
|
||||||
ty::TyRawPtr(_) |
|
|
||||||
ty::TyRef(..) |
|
|
||||||
ty::TyBareFn(..) |
|
|
||||||
ty::TySlice(_) |
|
|
||||||
ty::TyTrait(_) => {
|
|
||||||
/* nothing to do */
|
|
||||||
}
|
|
||||||
ty::TyStruct(ref adt_def, substs) |
|
|
||||||
ty::TyEnum(ref adt_def, substs) => {
|
|
||||||
for field in adt_def.all_fields() {
|
|
||||||
let field_type = monomorphize::apply_param_substs(ccx.tcx(),
|
|
||||||
substs,
|
|
||||||
&field.unsubst_ty());
|
|
||||||
visit_types_of_owned_components(ccx, field_type, visited, f);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::TyClosure(_, ref substs) => {
|
}
|
||||||
for upvar_ty in &substs.upvar_tys {
|
ty::TyBox(inner_type) |
|
||||||
visit_types_of_owned_components(ccx, upvar_ty, visited, f);
|
ty::TyArray(inner_type, _) => {
|
||||||
|
let inner_type = glue::get_drop_glue_type(ccx, inner_type);
|
||||||
|
if glue::type_needs_drop(ccx.tcx(), inner_type) {
|
||||||
|
output.push(TransItem::DropGlue(inner_type));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ty::TyTuple(ref args) => {
|
||||||
|
for arg in args {
|
||||||
|
let arg = glue::get_drop_glue_type(ccx, arg);
|
||||||
|
if glue::type_needs_drop(ccx.tcx(), arg) {
|
||||||
|
output.push(TransItem::DropGlue(arg));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ty::TyBox(inner_type) |
|
}
|
||||||
ty::TyArray(inner_type, _) => {
|
ty::TyProjection(_) |
|
||||||
visit_types_of_owned_components(ccx, inner_type, visited, f);
|
ty::TyParam(_) |
|
||||||
}
|
ty::TyInfer(_) |
|
||||||
ty::TyTuple(ref args) => {
|
ty::TyError => {
|
||||||
for arg in args {
|
ccx.sess().bug("encountered unexpected type");
|
||||||
visit_types_of_owned_components(ccx, arg, visited, f);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ty::TyProjection(_) |
|
|
||||||
ty::TyParam(_) |
|
|
||||||
ty::TyInfer(_) |
|
|
||||||
ty::TyError => {
|
|
||||||
ccx.sess().bug("encountered unexpected type");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1086,10 +1062,8 @@ impl<'b, 'a, 'v> hir_visit::Visitor<'v> for RootCollector<'b, 'a, 'v> {
|
|||||||
self.ccx.tcx().map.local_def_id(item.id),
|
self.ccx.tcx().map.local_def_id(item.id),
|
||||||
None));
|
None));
|
||||||
|
|
||||||
create_drop_glue_trans_items(self.ccx,
|
let ty = glue::get_drop_glue_type(self.ccx, ty);
|
||||||
ty,
|
self.output.push(TransItem::DropGlue(ty));
|
||||||
self.trans_empty_substs,
|
|
||||||
self.output);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user