diff options
| author | Oli Scherer <git-spam-no-reply9815368754983@oli-obk.de> | 2023-10-27 15:20:44 +0000 |
|---|---|---|
| committer | Oli Scherer <git-spam-no-reply9815368754983@oli-obk.de> | 2023-10-27 15:20:44 +0000 |
| commit | eb66d10cc3a6947cad6b4b169ed86b8c07f464d3 (patch) | |
| tree | 952788030c03803438bf32ddda62233ce6c28c33 /compiler/rustc_mir_transform/src | |
| parent | b8bfd08999babd4b70822c445eb7b016e1f52fab (diff) | |
| download | rust-eb66d10cc3a6947cad6b4b169ed86b8c07f464d3.tar.gz rust-eb66d10cc3a6947cad6b4b169ed86b8c07f464d3.zip | |
Fuse `gen` blocks
Diffstat (limited to 'compiler/rustc_mir_transform/src')
| -rw-r--r-- | compiler/rustc_mir_transform/src/coroutine.rs | 63 |
1 files changed, 49 insertions, 14 deletions
diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index 8fecff16a91..50d244d2831 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -249,18 +249,34 @@ struct TransformVisitor<'tcx> { } impl<'tcx> TransformVisitor<'tcx> { - // Make a `CoroutineState` or `Poll` variant assignment. - // - // `core::ops::CoroutineState` only has single element tuple variants, - // so we can just write to the downcasted first field and then set the - // discriminant to the appropriate variant. - fn make_state( + fn insert_none_ret_block(&self, body: &mut Body<'tcx>) -> BasicBlock { + let block = BasicBlock::new(body.basic_blocks.len()); + + let source_info = SourceInfo::outermost(body.span); + + let (kind, idx) = self.coroutine_state_adt_and_variant_idx(true); + assert_eq!(self.state_adt_ref.variant(idx).fields.len(), 0); + let statements = vec![Statement { + kind: StatementKind::Assign(Box::new(( + Place::return_place(), + Rvalue::Aggregate(Box::new(kind), IndexVec::new()), + ))), + source_info, + }]; + + body.basic_blocks_mut().push(BasicBlockData { + statements, + terminator: Some(Terminator { source_info, kind: TerminatorKind::Return }), + is_cleanup: false, + }); + + block + } + + fn coroutine_state_adt_and_variant_idx( &self, - val: Operand<'tcx>, - source_info: SourceInfo, is_return: bool, - statements: &mut Vec<Statement<'tcx>>, - ) { + ) -> (AggregateKind<'tcx>, VariantIdx) { let idx = VariantIdx::new(match (is_return, self.coroutine_kind) { (true, hir::CoroutineKind::Coroutine) => 1, // CoroutineState::Complete (false, hir::CoroutineKind::Coroutine) => 0, // CoroutineState::Yielded @@ -271,6 +287,22 @@ impl<'tcx> TransformVisitor<'tcx> { }); let kind = AggregateKind::Adt(self.state_adt_ref.did(), idx, self.state_args, None, None); + (kind, idx) + } + + // Make a `CoroutineState` or `Poll` variant assignment. + // + // `core::ops::CoroutineState` only has single element tuple variants, + // so we can just write to the downcasted first field and then set the + // discriminant to the appropriate variant. + fn make_state( + &self, + val: Operand<'tcx>, + source_info: SourceInfo, + is_return: bool, + statements: &mut Vec<Statement<'tcx>>, + ) { + let (kind, idx) = self.coroutine_state_adt_and_variant_idx(is_return); match self.coroutine_kind { // `Poll::Pending` @@ -1285,10 +1317,13 @@ fn create_coroutine_resume_function<'tcx>( } if can_return { - cases.insert( - 1, - (RETURNED, insert_panic_block(tcx, body, ResumedAfterReturn(coroutine_kind))), - ); + let block = match coroutine_kind { + CoroutineKind::Async(_) | CoroutineKind::Coroutine => { + insert_panic_block(tcx, body, ResumedAfterReturn(coroutine_kind)) + } + CoroutineKind::Gen(_) => transform.insert_none_ret_block(body), + }; + cases.insert(1, (RETURNED, block)); } insert_switch(body, cases, &transform, TerminatorKind::Unreachable); |
