Skip to content

Commit 26ec4cf

Browse files
committed
Refactoring for future layout only param dependency dedup
1 parent 84e7ad4 commit 26ec4cf

File tree

1 file changed

+69
-29
lines changed

1 file changed

+69
-29
lines changed

src/librustc_mir/monomorphize/deduplicate_instances.rs

Lines changed: 69 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99
// except according to those terms.
1010

1111
use rustc_data_structures::indexed_vec::IndexVec;
12-
use rustc::ty::{self, TyCtxt, Ty, TypeFoldable, Instance, ParamTy};
12+
use rustc::ty::{self, TyCtxt, Ty, TypeFoldable, Instance};
1313
use rustc::ty::fold::TypeFolder;
1414
use rustc::ty::subst::Kind;
1515
use rustc::middle::const_val::ConstVal;
16-
use rustc::mir::{Mir, Rvalue, Promoted, Location};
16+
use rustc::mir::{Mir, Rvalue, Location};
1717
use rustc::mir::visit::{Visitor, TyContext};
1818

1919
/// Replace substs which aren't used by the function with TyError,
@@ -53,7 +53,26 @@ pub(crate) fn collapse_interchangable_instances<'a, 'tcx>(
5353
let used_substs = used_substs_for_instance(tcx, instance);
5454
instance.substs = tcx._intern_substs(&instance.substs.into_iter().enumerate().map(|(i, subst)| {
5555
if let Some(ty) = subst.as_type() {
56-
let ty = if used_substs.substs.iter().find(|p|p.idx == i as u32).is_some() {
56+
/*let ty = if let ty::TyParam(ref _param) = ty.sty {
57+
match used_substs.parameters[ParamIdx(i as u32)] {
58+
ParamUsage::Unused => ty.into(),
59+
ParamUsage::LayoutUsed | ParamUsage::Used => {
60+
//^ Dont replace <closure_kind> and other internal params
61+
if false /*param.name.as_str().starts_with("<")*/ {
62+
ty.into()
63+
} else {
64+
tcx.sess.warn(&format!("Unused subst for {:?}", instance));
65+
tcx.mk_ty(ty::TyNever)
66+
}
67+
}
68+
}
69+
} else {
70+
tcx.sess.fatal("efjiofefio");
71+
// Can't use TyError as it gives some ICE in rustc_trans::callee::get_fn
72+
tcx.sess.warn(&format!("Unused subst for {:?}", instance));
73+
tcx.mk_ty(ty::TyNever)
74+
};*/
75+
let ty = if used_substs.parameters[ParamIdx(i as u32)] != ParamUsage::Unused {
5776
ty.into()
5877
} else if let ty::TyParam(ref _param) = ty.sty {
5978
//^ Dont replace <closure_kind> and other internal params
@@ -77,21 +96,59 @@ pub(crate) fn collapse_interchangable_instances<'a, 'tcx>(
7796
instance
7897
}
7998

99+
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
100+
struct ParamIdx(u32);
101+
102+
impl ::rustc_data_structures::indexed_vec::Idx for ParamIdx {
103+
fn new(idx: usize) -> Self {
104+
assert!(idx < ::std::u32::MAX as usize);
105+
ParamIdx(idx as u32)
106+
}
107+
108+
fn index(self) -> usize {
109+
self.0 as usize
110+
}
111+
}
112+
113+
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
114+
enum ParamUsage {
115+
Unused = 0,
116+
#[allow(dead_code)]
117+
LayoutUsed = 1,
118+
Used = 2,
119+
}
120+
121+
impl_stable_hash_for! { enum self::ParamUsage { Unused, LayoutUsed, Used} }
122+
80123
#[derive(Debug, Default, Clone)]
81-
pub struct UsedParameters {
82-
pub parameters: Vec<ParamTy>,
83-
pub promoted: IndexVec<Promoted, UsedParameters>,
124+
pub struct ParamsUsage {
125+
parameters: IndexVec<ParamIdx, ParamUsage>,
84126
}
85127

86-
impl_stable_hash_for! { struct UsedParameters { substs, promoted } }
128+
impl_stable_hash_for! { struct ParamsUsage { parameters } }
129+
130+
impl ParamsUsage {
131+
fn new(len: usize) -> ParamsUsage {
132+
ParamsUsage {
133+
parameters: IndexVec::from_elem_n(ParamUsage::Unused, len),
134+
}
135+
}
136+
}
87137

88138
struct SubstsVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a>(
89139
TyCtxt<'a, 'gcx, 'tcx>,
90140
&'tcx Mir<'tcx>,
91-
UsedParameters,
141+
ParamsUsage,
92142
);
93143

94144
impl<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> Visitor<'tcx> for SubstsVisitor<'a, 'gcx, 'tcx> {
145+
fn visit_mir(&mut self, mir: &Mir<'tcx>) {
146+
for promoted in &mir.promoted {
147+
self.visit_mir(promoted);
148+
}
149+
self.super_mir(mir);
150+
}
151+
95152
fn visit_ty(&mut self, ty: &Ty<'tcx>, _: TyContext) {
96153
self.fold_ty(ty);
97154
}
@@ -129,7 +186,7 @@ impl<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> TypeFolder<'gcx, 'tcx> for SubstsVisitor<'a,
129186
}
130187
match ty.sty {
131188
ty::TyParam(param) => {
132-
self.2.parameters.push(param);
189+
self.2.parameters[ParamIdx(param.idx)] = ParamUsage::Used;
133190
ty
134191
}
135192
ty::TyFnDef(_, substs) => {
@@ -156,32 +213,15 @@ impl<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> TypeFolder<'gcx, 'tcx> for SubstsVisitor<'a,
156213
fn used_substs_for_instance<'a, 'tcx: 'a>(
157214
tcx: TyCtxt<'a ,'tcx, 'tcx>,
158215
instance: Instance<'tcx>,
159-
) -> UsedParameters {
216+
) -> ParamsUsage {
160217
let mir = tcx.instance_mir(instance.def);
161218
let sig = ::rustc::ty::ty_fn_sig(tcx, instance.ty(tcx));
162219
let sig = tcx.erase_late_bound_regions_and_normalize(&sig);
163-
let mut substs_visitor = SubstsVisitor(tcx, mir, UsedParameters::default());
220+
let mut substs_visitor = SubstsVisitor(tcx, mir, ParamsUsage::new(instance.substs.len()));
164221
substs_visitor.visit_mir(mir);
165222
for ty in sig.inputs().iter() {
166223
ty.fold_with(&mut substs_visitor);
167224
}
168225
sig.output().fold_with(&mut substs_visitor);
169-
let mut used_substs = substs_visitor.2;
170-
used_substs.parameters.sort_by_key(|s|s.idx);
171-
used_substs.parameters.dedup_by_key(|s|s.idx);
172-
used_substs.promoted = mir.promoted.iter().map(|mir| used_substs_for_mir(tcx, mir)).collect();
173-
used_substs
174-
}
175-
176-
fn used_substs_for_mir<'a, 'tcx: 'a>(
177-
tcx: TyCtxt<'a ,'tcx, 'tcx>,
178-
mir: &'tcx Mir<'tcx>,
179-
) -> UsedParameters {
180-
let mut substs_visitor = SubstsVisitor(tcx, mir, UsedParameters::default());
181-
substs_visitor.visit_mir(mir);
182-
let mut used_substs = substs_visitor.2;
183-
used_substs.parameters.sort_by_key(|s|s.idx);
184-
used_substs.parameters.dedup_by_key(|s|s.idx);
185-
used_substs.promoted = mir.promoted.iter().map(|mir| used_substs_for_mir(tcx, mir)).collect();
186-
used_substs
226+
substs_visitor.2
187227
}

0 commit comments

Comments
 (0)