Skip to content

Commit bea0a42

Browse files
committed
Perform generator field computation before optimizations
1 parent 6840bc4 commit bea0a42

File tree

4 files changed

+58
-10
lines changed

4 files changed

+58
-10
lines changed

src/librustc/mir/mod.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ use syntax::symbol::Symbol;
3838
use syntax_pos::{Span, DUMMY_SP};
3939

4040
pub use crate::mir::interpret::AssertMessage;
41-
pub use crate::mir::cache::{BodyCache, ReadOnlyBodyCache};
41+
pub use crate::mir::cache::{Cache, BodyCache, ReadOnlyBodyCache};
4242
pub use crate::read_only;
4343

4444
mod cache;
@@ -117,6 +117,8 @@ pub struct Body<'tcx> {
117117
/// to be created.
118118
pub generator_kind: Option<GeneratorKind>,
119119

120+
pub generator_interior_tys: Option<Vec<Ty<'tcx>>>,
121+
120122
/// Declarations of locals.
121123
///
122124
/// The first local is the return value pointer, followed by `arg_count`
@@ -184,6 +186,7 @@ impl<'tcx> Body<'tcx> {
184186
generator_drop: None,
185187
generator_layout: None,
186188
generator_kind,
189+
generator_interior_tys: None,
187190
local_decls,
188191
user_type_annotations,
189192
arg_count,

src/librustc/traits/select.rs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2755,9 +2755,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
27552755
ty::GeneratorWitness(did, types) => {
27562756
// Note that we need to use optimized_mir here,
27572757
// in order to have the `StateTransform` pass run
2758-
let gen_mir = self.tcx().optimized_mir(did);
2758+
/*let gen_mir = self.tcx().optimized_mir(did);
27592759
let gen_layout = gen_mir.generator_layout.as_ref()
2760-
.expect("Missing generator layout!");
2760+
.expect("Missing generator layout!");*/
27612761

27622762
// We need to compare the types from the GeneratoWitness
27632763
// to the types from the MIR. Since the generator MIR (specifically
@@ -2806,7 +2806,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
28062806

28072807
let mut used_types = Vec::new();
28082808

2809-
for ty in &gen_layout.field_tys {
2809+
// Note - while we use `optimized_mir`, the .generator_interior_tys
2810+
// field is only set during construction of the original MIR,
2811+
// and is unaffected by optimizations
2812+
let interior_tys = self.tcx().optimized_mir(did).generator_interior_tys
2813+
.as_ref().expect("Missing generator interior types!");
2814+
2815+
//for ty in &gen_layout.field_tys {
2816+
for ty in interior_tys {
28102817
if let Some(witness_ty) = erased_types.get(&self.tcx().erase_regions(ty)) {
28112818
used_types.push(**witness_ty);
28122819
}

src/librustc_mir/transform/generator.rs

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -757,10 +757,11 @@ fn compute_layout<'tcx>(
757757
GeneratorLayout<'tcx>,
758758
FxHashMap<BasicBlock, liveness::LiveVarSet>,
759759
) {
760+
760761
// Use a liveness analysis to compute locals which are live across a suspension point
761-
let LivenessInfo {
762+
let (LivenessInfo {
762763
live_locals, live_locals_at_suspension_points, storage_conflicts, storage_liveness
763-
} = locals_live_across_suspend_points(tcx, read_only!(body), source, movable);
764+
}, tys) = compute_field_tys(tcx, source, movable, read_only!(body));
764765

765766
// Erase regions from the types passed in from typeck so we can compare them with
766767
// MIR types
@@ -789,10 +790,8 @@ fn compute_layout<'tcx>(
789790

790791
// Gather live local types and their indices.
791792
let mut locals = IndexVec::<GeneratorSavedLocal, _>::new();
792-
let mut tys = IndexVec::<GeneratorSavedLocal, _>::new();
793793
for (idx, local) in live_locals.iter().enumerate() {
794794
locals.push(local);
795-
tys.push(body.local_decls[local].ty);
796795
debug!("generator saved local {:?} => {:?}", GeneratorSavedLocal::from(idx), local);
797796
}
798797

@@ -1168,6 +1167,40 @@ where
11681167
}).collect()
11691168
}
11701169

1170+
pub(super) fn generator_interior_tys<'tcx>(
1171+
tcx: TyCtxt<'tcx>,
1172+
def_id: DefId,
1173+
body: &BodyCache<'tcx>
1174+
) -> Vec<Ty<'tcx>> {
1175+
// The first argument is the generator type passed by value
1176+
//let gen_ty = body.local_decls.raw[1].tyi;
1177+
let gen_ty = tcx.type_of(def_id);
1178+
let movable = match gen_ty.kind {
1179+
ty::Generator(_, _, movability) => {
1180+
movability == hir::Movability::Movable
1181+
},
1182+
_ => bug!("Unexpected type {:?}", gen_ty)
1183+
};
1184+
1185+
compute_field_tys(tcx, MirSource::item(def_id), movable, body.unwrap_read_only()).1.raw
1186+
}
1187+
1188+
fn compute_field_tys(
1189+
tcx: TyCtxt<'tcx>,
1190+
source: MirSource<'tcx>,
1191+
movable: bool,
1192+
body: ReadOnlyBodyCache<'_, 'tcx>
1193+
) -> (LivenessInfo, IndexVec<GeneratorSavedLocal, Ty<'tcx>>) {
1194+
let liveness_info = locals_live_across_suspend_points(
1195+
tcx, body, source, movable
1196+
);
1197+
let mut tys = IndexVec::<GeneratorSavedLocal, _>::new();
1198+
for local in liveness_info.live_locals.iter() {
1199+
tys.push(body.local_decls[local].ty);
1200+
}
1201+
(liveness_info, tys)
1202+
}
1203+
11711204
impl<'tcx> MirPass<'tcx> for StateTransform {
11721205
fn run_pass(
11731206
&self, tcx: TyCtxt<'tcx>, source: MirSource<'tcx>, body: &mut BodyCache<'tcx>

src/librustc_mir/transform/mod.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::{build, shim};
22
use rustc_index::vec::IndexVec;
33
use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
44
use rustc::mir::{BodyCache, MirPhase, Promoted, ConstQualifs};
5-
use rustc::ty::{TyCtxt, InstanceDef, TypeFoldable};
5+
use rustc::ty::{self, TyCtxt, InstanceDef, TypeFoldable};
66
use rustc::ty::query::Providers;
77
use rustc::ty::steal::Steal;
88
use rustc::hir;
@@ -98,7 +98,12 @@ fn mir_keys(tcx: TyCtxt<'_>, krate: CrateNum) -> &DefIdSet {
9898
}
9999

100100
fn mir_built(tcx: TyCtxt<'_>, def_id: DefId) -> &Steal<BodyCache<'_>> {
101-
let mir = build::mir_build(tcx, def_id);
101+
let mut mir = build::mir_build(tcx, def_id);
102+
if let ty::Generator(..) = tcx.type_of(def_id).kind {
103+
let interior_types = generator::generator_interior_tys(tcx, def_id, &mir);
104+
mir.generator_interior_tys = Some(interior_types);
105+
}
106+
102107
tcx.alloc_steal_mir(mir)
103108
}
104109

0 commit comments

Comments
 (0)