|
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