|
112 | 112 | use crate::transform::{MirPass, MirSource}; |
113 | 113 | use rustc_index::{bit_set::BitSet, vec::IndexVec}; |
114 | 114 | use rustc_middle::mir::tcx::PlaceTy; |
115 | | -use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor, MutatingUseContext}; |
| 115 | +use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor}; |
116 | 116 | use rustc_middle::mir::{ |
117 | | - read_only, Body, BodyAndCache, Local, LocalKind, Location, Operand, Place, PlaceElem, |
118 | | - ReadOnlyBodyAndCache, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, |
119 | | - BasicBlock, |
| 117 | + read_only, BasicBlock, Body, BodyAndCache, Local, LocalKind, Location, Operand, Place, |
| 118 | + PlaceElem, ReadOnlyBodyAndCache, Rvalue, Statement, StatementKind, Terminator, TerminatorKind, |
120 | 119 | }; |
121 | 120 | use rustc_middle::ty::{self, Ty, TyCtxt}; |
122 | | -use std::collections::VecDeque; |
123 | 121 | use rustc_span::def_id::LOCAL_CRATE; |
| 122 | +use std::collections::VecDeque; |
124 | 123 |
|
125 | 124 | pub struct Nrvo; |
126 | 125 |
|
@@ -166,11 +165,27 @@ impl<'tcx> MirPass<'tcx> for Nrvo { |
166 | 165 | debug!("{:?} = {:?} at {:?}", dest, src, loc); |
167 | 166 | debug!("usage_map[src] = {:?}", usage_map[src]); |
168 | 167 | debug!("usage_map[dest.local] = {:?}", usage_map[dest.local]); |
169 | | - if expect_uses_relative_to(src, loc, Direction::Backward, &usage_map[src], &read_only!(body)).is_err() { |
| 168 | + if expect_uses_relative_to( |
| 169 | + src, |
| 170 | + loc, |
| 171 | + Direction::Backward, |
| 172 | + &usage_map[src], |
| 173 | + &read_only!(body), |
| 174 | + ) |
| 175 | + .is_err() |
| 176 | + { |
170 | 177 | debug!("(ineligible, src used after assignment)"); |
171 | 178 | return false; |
172 | 179 | } |
173 | | - if expect_uses_relative_to(dest.local, loc, Direction::Forward, &usage_map[dest.local], &read_only!(body)).is_err() { |
| 180 | + if expect_uses_relative_to( |
| 181 | + dest.local, |
| 182 | + loc, |
| 183 | + Direction::Forward, |
| 184 | + &usage_map[dest.local], |
| 185 | + &read_only!(body), |
| 186 | + ) |
| 187 | + .is_err() |
| 188 | + { |
174 | 189 | debug!("(ineligible, dest used before assignment)"); |
175 | 190 | return false; |
176 | 191 | } |
@@ -382,16 +397,18 @@ fn expect_uses_relative_to( |
382 | 397 | // We're interested in uses of `local` basically before or after the `=` sign of the assignment. |
383 | 398 | // That mean we have to visit one half of the assign statement here. |
384 | 399 | match &statements[loc.statement_index].kind { |
385 | | - StatementKind::Assign(box (place, rvalue)) => { |
386 | | - match dir { |
387 | | - Direction::Backward => { |
388 | | - collector.visit_rvalue(rvalue, loc); |
389 | | - } |
390 | | - Direction::Forward => { |
391 | | - collector.visit_place(place, PlaceContext::MutatingUse(MutatingUseContext::Store), loc); |
392 | | - } |
| 400 | + StatementKind::Assign(box (place, rvalue)) => match dir { |
| 401 | + Direction::Backward => { |
| 402 | + collector.visit_rvalue(rvalue, loc); |
393 | 403 | } |
394 | | - } |
| 404 | + Direction::Forward => { |
| 405 | + collector.visit_place( |
| 406 | + place, |
| 407 | + PlaceContext::MutatingUse(MutatingUseContext::Store), |
| 408 | + loc, |
| 409 | + ); |
| 410 | + } |
| 411 | + }, |
395 | 412 | _ => bug!("{:?} should be an assignment", loc), |
396 | 413 | } |
397 | 414 |
|
@@ -463,7 +480,8 @@ type UsageMap = IndexVec<Local, BitSet<BasicBlock>>; |
463 | 480 |
|
464 | 481 | /// Builds a usage map, mapping `Local`s to the `BasicBlock`s using them. |
465 | 482 | fn usage_map(body: &Body<'_>) -> UsageMap { |
466 | | - let mut map = IndexVec::from_elem_n(BitSet::new_empty(body.basic_blocks().len()), body.local_decls.len()); |
| 483 | + let mut map = |
| 484 | + IndexVec::from_elem_n(BitSet::new_empty(body.basic_blocks().len()), body.local_decls.len()); |
467 | 485 | let mut collector = UseCollector { |
468 | 486 | callback: |local, location: Location| { |
469 | 487 | map[local].insert(location.block); |
|
0 commit comments