Skip to content

Commit 4d074b8

Browse files
Avoid redundant work for drop-glue translation items in trans::collector
1 parent 9e96980 commit 4d074b8

File tree

1 file changed

+109
-135
lines changed

1 file changed

+109
-135
lines changed

src/librustc_trans/trans/collector.rs

+109-135
Original file line numberDiff line numberDiff line change
@@ -350,14 +350,14 @@ fn collect_items_rec<'a, 'tcx: 'a>(ccx: &CrateContext<'a, 'tcx>,
350350
let recursion_depth_reset;
351351

352352
match starting_point {
353-
TransItem::DropGlue(_) |
353+
TransItem::DropGlue(t) => {
354+
find_drop_glue_neighbors(ccx, t, &mut neighbors);
355+
recursion_depth_reset = None;
356+
}
354357
TransItem::Static(_) => {
355358
recursion_depth_reset = None;
356359
}
357-
TransItem::Fn {
358-
def_id,
359-
substs: ref param_substs
360-
} => {
360+
TransItem::Fn { def_id, substs: ref param_substs } => {
361361
// Keep track of the monomorphization recursion depth
362362
recursion_depth_reset = Some(check_recursion_limit(ccx,
363363
def_id,
@@ -531,11 +531,8 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
531531
self.param_substs,
532532
&ty);
533533
let ty = self.ccx.tcx().erase_regions(&ty);
534-
535-
create_drop_glue_trans_items(self.ccx,
536-
ty,
537-
self.param_substs,
538-
&mut self.output);
534+
let ty = glue::get_drop_glue_type(self.ccx, ty);
535+
self.output.push(TransItem::DropGlue(ty));
539536
}
540537

541538
self.super_lvalue(lvalue, context);
@@ -636,145 +633,124 @@ fn can_have_local_instance<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
636633
def_id.is_local() || ccx.sess().cstore.is_item_mir_available(def_id)
637634
}
638635

639-
fn create_drop_glue_trans_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
640-
mono_ty: ty::Ty<'tcx>,
641-
param_substs: &'tcx Substs<'tcx>,
642-
output: &mut Vec<TransItem<'tcx>>)
636+
fn find_drop_glue_neighbors<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
637+
ty: ty::Ty<'tcx>,
638+
output: &mut Vec<TransItem<'tcx>>)
643639
{
644-
visit_types_of_owned_components(ccx,
645-
mono_ty,
646-
&mut FnvHashSet(),
647-
&mut |ty| {
648-
debug!("create_drop_glue_trans_items: {}", type_to_string(ccx, ty));
649-
// Add a translation item for the drop glue, if even this type does not
650-
// need to be dropped (in which case it has been mapped to i8)
651-
output.push(TransItem::DropGlue(ty));
652-
653-
if glue::type_needs_drop(ccx.tcx(), ty) {
654-
655-
// Make sure the exchange_free_fn() lang-item gets translated if
656-
// there is a boxed value.
657-
if let ty::TyBox(_) = ty.sty {
658-
659-
let exchange_free_fn_def_id = ccx.tcx()
660-
.lang_items
661-
.require(ExchangeFreeFnLangItem)
662-
.expect("Could not find ExchangeFreeFnLangItem");
663-
664-
assert!(can_have_local_instance(ccx, exchange_free_fn_def_id));
665-
let exchange_free_fn_trans_item =
666-
create_fn_trans_item(ccx,
667-
exchange_free_fn_def_id,
668-
&Substs::trans_empty(),
669-
param_substs);
670-
671-
output.push(exchange_free_fn_trans_item);
672-
}
673-
674-
// If the type implements Drop, also add a translation item for the
675-
// monomorphized Drop::drop() implementation.
676-
let destructor_did = match ty.sty {
677-
ty::TyStruct(def, _) |
678-
ty::TyEnum(def, _) => def.destructor(),
679-
_ => None
680-
};
681-
682-
if let Some(destructor_did) = destructor_did {
683-
use rustc::middle::ty::ToPolyTraitRef;
640+
debug!("find_drop_glue_neighbors: {}", type_to_string(ccx, ty));
641+
642+
// Make sure the exchange_free_fn() lang-item gets translated if
643+
// there is a boxed value.
644+
if let ty::TyBox(_) = ty.sty {
645+
let exchange_free_fn_def_id = ccx.tcx()
646+
.lang_items
647+
.require(ExchangeFreeFnLangItem)
648+
.expect("Could not find ExchangeFreeFnLangItem");
649+
650+
assert!(can_have_local_instance(ccx, exchange_free_fn_def_id));
651+
let exchange_free_fn_trans_item =
652+
create_fn_trans_item(ccx,
653+
exchange_free_fn_def_id,
654+
&Substs::trans_empty(),
655+
&Substs::trans_empty());
656+
657+
output.push(exchange_free_fn_trans_item);
658+
}
684659

685-
let drop_trait_def_id = ccx.tcx()
686-
.lang_items
687-
.drop_trait()
688-
.unwrap();
660+
// If the type implements Drop, also add a translation item for the
661+
// monomorphized Drop::drop() implementation.
662+
let destructor_did = match ty.sty {
663+
ty::TyStruct(def, _) |
664+
ty::TyEnum(def, _) => def.destructor(),
665+
_ => None
666+
};
689667

690-
let self_type_substs = ccx.tcx().mk_substs(
691-
Substs::trans_empty().with_self_ty(ty));
668+
if let Some(destructor_did) = destructor_did {
669+
use rustc::middle::ty::ToPolyTraitRef;
692670

693-
let trait_ref = ty::TraitRef {
694-
def_id: drop_trait_def_id,
695-
substs: self_type_substs,
696-
}.to_poly_trait_ref();
671+
let drop_trait_def_id = ccx.tcx()
672+
.lang_items
673+
.drop_trait()
674+
.unwrap();
697675

698-
let substs = match fulfill_obligation(ccx, DUMMY_SP, trait_ref) {
699-
traits::VtableImpl(data) => data.substs,
700-
_ => unreachable!()
701-
};
702-
703-
if can_have_local_instance(ccx, destructor_did) {
704-
let trans_item = create_fn_trans_item(ccx,
705-
destructor_did,
706-
ccx.tcx().mk_substs(substs),
707-
param_substs);
708-
output.push(trans_item);
709-
}
710-
}
676+
let self_type_substs = ccx.tcx().mk_substs(
677+
Substs::trans_empty().with_self_ty(ty));
711678

712-
true
713-
} else {
714-
false
715-
}
716-
});
679+
let trait_ref = ty::TraitRef {
680+
def_id: drop_trait_def_id,
681+
substs: self_type_substs,
682+
}.to_poly_trait_ref();
717683

718-
fn visit_types_of_owned_components<'a, 'tcx, F>(ccx: &CrateContext<'a, 'tcx>,
719-
ty: ty::Ty<'tcx>,
720-
visited: &mut FnvHashSet<ty::Ty<'tcx>>,
721-
mut f: &mut F)
722-
where F: FnMut(ty::Ty<'tcx>) -> bool
723-
{
724-
let ty = glue::get_drop_glue_type(ccx, ty);
684+
let substs = match fulfill_obligation(ccx, DUMMY_SP, trait_ref) {
685+
traits::VtableImpl(data) => data.substs,
686+
_ => unreachable!()
687+
};
725688

726-
if !visited.insert(ty) {
727-
return;
689+
if can_have_local_instance(ccx, destructor_did) {
690+
let trans_item = create_fn_trans_item(ccx,
691+
destructor_did,
692+
ccx.tcx().mk_substs(substs),
693+
&Substs::trans_empty());
694+
output.push(trans_item);
728695
}
696+
}
729697

730-
if !f(ty) {
731-
// Don't recurse further
732-
return;
698+
// Finally add the types of nested values
699+
match ty.sty {
700+
ty::TyBool |
701+
ty::TyChar |
702+
ty::TyInt(_) |
703+
ty::TyUint(_) |
704+
ty::TyStr |
705+
ty::TyFloat(_) |
706+
ty::TyRawPtr(_) |
707+
ty::TyRef(..) |
708+
ty::TyBareFn(..) |
709+
ty::TySlice(_) |
710+
ty::TyTrait(_) => {
711+
/* nothing to do */
733712
}
734-
735-
match ty.sty {
736-
ty::TyBool |
737-
ty::TyChar |
738-
ty::TyInt(_) |
739-
ty::TyUint(_) |
740-
ty::TyStr |
741-
ty::TyFloat(_) |
742-
ty::TyRawPtr(_) |
743-
ty::TyRef(..) |
744-
ty::TyBareFn(..) |
745-
ty::TySlice(_) |
746-
ty::TyTrait(_) => {
747-
/* nothing to do */
748-
}
749-
ty::TyStruct(ref adt_def, substs) |
750-
ty::TyEnum(ref adt_def, substs) => {
751-
for field in adt_def.all_fields() {
752-
let field_type = monomorphize::apply_param_substs(ccx.tcx(),
753-
substs,
754-
&field.unsubst_ty());
755-
visit_types_of_owned_components(ccx, field_type, visited, f);
713+
ty::TyStruct(ref adt_def, substs) |
714+
ty::TyEnum(ref adt_def, substs) => {
715+
for field in adt_def.all_fields() {
716+
let field_type = monomorphize::apply_param_substs(ccx.tcx(),
717+
substs,
718+
&field.unsubst_ty());
719+
let field_type = glue::get_drop_glue_type(ccx, field_type);
720+
721+
if glue::type_needs_drop(ccx.tcx(), field_type) {
722+
output.push(TransItem::DropGlue(field_type));
756723
}
757724
}
758-
ty::TyClosure(_, ref substs) => {
759-
for upvar_ty in &substs.upvar_tys {
760-
visit_types_of_owned_components(ccx, upvar_ty, visited, f);
725+
}
726+
ty::TyClosure(_, ref substs) => {
727+
for upvar_ty in &substs.upvar_tys {
728+
let upvar_ty = glue::get_drop_glue_type(ccx, upvar_ty);
729+
if glue::type_needs_drop(ccx.tcx(), upvar_ty) {
730+
output.push(TransItem::DropGlue(upvar_ty));
761731
}
762732
}
763-
ty::TyBox(inner_type) |
764-
ty::TyArray(inner_type, _) => {
765-
visit_types_of_owned_components(ccx, inner_type, visited, f);
733+
}
734+
ty::TyBox(inner_type) |
735+
ty::TyArray(inner_type, _) => {
736+
let inner_type = glue::get_drop_glue_type(ccx, inner_type);
737+
if glue::type_needs_drop(ccx.tcx(), inner_type) {
738+
output.push(TransItem::DropGlue(inner_type));
766739
}
767-
ty::TyTuple(ref args) => {
768-
for arg in args {
769-
visit_types_of_owned_components(ccx, arg, visited, f);
740+
}
741+
ty::TyTuple(ref args) => {
742+
for arg in args {
743+
let arg = glue::get_drop_glue_type(ccx, arg);
744+
if glue::type_needs_drop(ccx.tcx(), arg) {
745+
output.push(TransItem::DropGlue(arg));
770746
}
771747
}
772-
ty::TyProjection(_) |
773-
ty::TyParam(_) |
774-
ty::TyInfer(_) |
775-
ty::TyError => {
776-
ccx.sess().bug("encountered unexpected type");
777-
}
748+
}
749+
ty::TyProjection(_) |
750+
ty::TyParam(_) |
751+
ty::TyInfer(_) |
752+
ty::TyError => {
753+
ccx.sess().bug("encountered unexpected type");
778754
}
779755
}
780756
}
@@ -1086,10 +1062,8 @@ impl<'b, 'a, 'v> hir_visit::Visitor<'v> for RootCollector<'b, 'a, 'v> {
10861062
self.ccx.tcx().map.local_def_id(item.id),
10871063
None));
10881064

1089-
create_drop_glue_trans_items(self.ccx,
1090-
ty,
1091-
self.trans_empty_substs,
1092-
self.output);
1065+
let ty = glue::get_drop_glue_type(self.ccx, ty);
1066+
self.output.push(TransItem::DropGlue(ty));
10931067
}
10941068
}
10951069
}

0 commit comments

Comments
 (0)