-
Notifications
You must be signed in to change notification settings - Fork 12.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Auto merge of #44480 - Zoxc:gen-liveness, r=arielb1
Analyse storage liveness and preserve it during generator transformation This uses a dataflow analysis on `StorageLive` and `StorageDead` statements to infer where the storage of locals are live. The result of this analysis is intersected with the regular liveness analysis such that a local is can only be live when its storage is. This fixes #44184. If the storage of a local is live across a suspension point, we'll insert a `StorageLive` statement for it after the suspension point so storage liveness is preserved. This fixes #44179. r? @arielb1
- Loading branch information
Showing
7 changed files
with
354 additions
and
174 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
// Copyright 2017 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
pub use super::*; | ||
|
||
use rustc::mir::*; | ||
use dataflow::BitDenotation; | ||
|
||
#[derive(Copy, Clone)] | ||
pub struct MaybeStorageLive<'a, 'tcx: 'a> { | ||
mir: &'a Mir<'tcx>, | ||
} | ||
|
||
impl<'a, 'tcx: 'a> MaybeStorageLive<'a, 'tcx> { | ||
pub fn new(mir: &'a Mir<'tcx>) | ||
-> Self { | ||
MaybeStorageLive { mir: mir } | ||
} | ||
|
||
pub fn mir(&self) -> &Mir<'tcx> { | ||
self.mir | ||
} | ||
} | ||
|
||
impl<'a, 'tcx> BitDenotation for MaybeStorageLive<'a, 'tcx> { | ||
type Idx = Local; | ||
fn name() -> &'static str { "maybe_storage_live" } | ||
fn bits_per_block(&self) -> usize { | ||
self.mir.local_decls.len() | ||
} | ||
|
||
fn start_block_effect(&self, _sets: &mut BlockSets<Local>) { | ||
// Nothing is live on function entry | ||
} | ||
|
||
fn statement_effect(&self, | ||
sets: &mut BlockSets<Local>, | ||
loc: Location) { | ||
let stmt = &self.mir[loc.block].statements[loc.statement_index]; | ||
|
||
match stmt.kind { | ||
StatementKind::StorageLive(l) => sets.gen(&l), | ||
StatementKind::StorageDead(l) => sets.kill(&l), | ||
_ => (), | ||
} | ||
} | ||
|
||
fn terminator_effect(&self, | ||
_sets: &mut BlockSets<Local>, | ||
_loc: Location) { | ||
// Terminators have no effect | ||
} | ||
|
||
fn propagate_call_return(&self, | ||
_in_out: &mut IdxSet<Local>, | ||
_call_bb: mir::BasicBlock, | ||
_dest_bb: mir::BasicBlock, | ||
_dest_lval: &mir::Lvalue) { | ||
// Nothing to do when a call returns successfully | ||
} | ||
} | ||
|
||
impl<'a, 'tcx> BitwiseOperator for MaybeStorageLive<'a, 'tcx> { | ||
#[inline] | ||
fn join(&self, pred1: usize, pred2: usize) -> usize { | ||
pred1 | pred2 // "maybe" means we union effects of both preds | ||
} | ||
} | ||
|
||
impl<'a, 'tcx> DataflowOperator for MaybeStorageLive<'a, 'tcx> { | ||
#[inline] | ||
fn bottom_value() -> bool { | ||
false // bottom = dead | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.