Skip to content

Commit 2eed90a

Browse files
committed
Account for new maybe_sideeffect helper that requires predecessors
1 parent c8c266a commit 2eed90a

File tree

10 files changed

+176
-133
lines changed

10 files changed

+176
-133
lines changed

src/librustc/mir/cache.rs

Lines changed: 115 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,7 @@ impl Cache {
4747
}
4848

4949
#[inline]
50-
/// This will recompute the predecessors cache if it is not available
51-
pub fn predecessors(&mut self, body: &Body<'_>) -> &IndexVec<BasicBlock, Vec<BasicBlock>> {
50+
pub fn ensure_predecessors(&mut self, body: &Body<'_>) {
5251
if self.predecessors.is_none() {
5352
let mut result = IndexVec::from_elem(vec![], body.basic_blocks());
5453
for (bb, data) in body.basic_blocks().iter_enumerated() {
@@ -61,7 +60,12 @@ impl Cache {
6160

6261
self.predecessors = Some(result)
6362
}
63+
}
6464

65+
#[inline]
66+
/// This will recompute the predecessors cache if it is not available
67+
pub fn predecessors(&mut self, body: &Body<'_>) -> &IndexVec<BasicBlock, Vec<BasicBlock>> {
68+
self.ensure_predecessors(body);
6569
self.predecessors.as_ref().unwrap()
6670
}
6771

@@ -70,6 +74,11 @@ impl Cache {
7074
&self.predecessors(body)[bb]
7175
}
7276

77+
#[inline]
78+
fn unwrap_predecessors_for(&self, bb: BasicBlock) -> &[BasicBlock] {
79+
&self.predecessors.as_ref().unwrap()[bb]
80+
}
81+
7382
#[inline]
7483
pub fn predecessor_locations<'a>(&'a mut self, loc: Location, body: &'a Body<'a>) -> impl Iterator<Item = Location> + 'a {
7584
let if_zero_locations = if loc.statement_index == 0 {
@@ -137,13 +146,17 @@ impl<'a, 'tcx> BodyCache<&'a Body<'tcx>> {
137146
}
138147

139148
#[inline]
140-
pub fn basic_blocks(&self) -> &IndexVec<BasicBlock, BasicBlockData<'tcx>> {
141-
&self.body.basic_blocks
149+
pub fn read_only(mut self) -> ReadOnlyBodyCache<'a, 'tcx> {
150+
self.cache.ensure_predecessors(self.body);
151+
ReadOnlyBodyCache {
152+
cache: self.cache,
153+
body: self.body,
154+
}
142155
}
143156

144157
#[inline]
145-
pub fn dominators(&mut self) -> Dominators<BasicBlock> {
146-
dominators(self)
158+
pub fn basic_blocks(&self) -> &IndexVec<BasicBlock, BasicBlockData<'tcx>> {
159+
&self.body.basic_blocks
147160
}
148161
}
149162

@@ -164,50 +177,6 @@ impl<'a, 'tcx> Index<BasicBlock> for BodyCache<&'a Body<'tcx>> {
164177
}
165178
}
166179

167-
impl<'a, 'tcx> graph::DirectedGraph for BodyCache<&'a Body<'tcx>> {
168-
type Node = BasicBlock;
169-
}
170-
171-
impl<'a, 'graph, 'tcx> graph::GraphPredecessors<'graph> for BodyCache<&'a Body<'tcx>> {
172-
type Item = BasicBlock;
173-
type Iter = IntoIter<BasicBlock>;
174-
}
175-
176-
impl<'a, 'tcx> graph::WithPredecessors for BodyCache<&'a Body<'tcx>> {
177-
fn predecessors(
178-
&mut self,
179-
node: Self::Node,
180-
) -> <Self as GraphPredecessors<'_>>::Iter {
181-
self.predecessors_for(node).to_vec().into_iter()
182-
}
183-
}
184-
185-
impl<'a, 'tcx> graph::WithNumNodes for BodyCache<&'a Body<'tcx>> {
186-
fn num_nodes(&self) -> usize {
187-
self.body.num_nodes()
188-
}
189-
}
190-
191-
impl<'a, 'tcx> graph::WithStartNode for BodyCache<&'a Body<'tcx>> {
192-
fn start_node(&self) -> Self::Node {
193-
self.body.start_node()
194-
}
195-
}
196-
197-
impl<'a, 'tcx> graph::WithSuccessors for BodyCache<&'a Body<'tcx>> {
198-
fn successors(
199-
&self,
200-
node: Self::Node,
201-
) -> <Self as GraphSuccessors<'_>>::Iter {
202-
self.body.successors(node)
203-
}
204-
}
205-
206-
impl<'a, 'b, 'tcx> graph::GraphSuccessors<'b> for BodyCache<&'a Body<'tcx>> {
207-
type Item = BasicBlock;
208-
type Iter = iter::Cloned<Successors<'b>>;
209-
}
210-
211180
impl<'a, 'tcx> BodyCache<&'a mut Body<'tcx>> {
212181
#[inline]
213182
pub fn body(&self) -> &Body<'tcx> {
@@ -259,3 +228,99 @@ impl<'a, 'tcx> IndexMut<BasicBlock> for BodyCache<&'a mut Body<'tcx>> {
259228
&mut self.body.basic_blocks[index]
260229
}
261230
}
231+
232+
pub struct ReadOnlyBodyCache<'a, 'tcx> {
233+
cache: Cache,
234+
body: &'a Body<'tcx>,
235+
}
236+
237+
impl ReadOnlyBodyCache<'a, 'tcx> {
238+
#[inline]
239+
pub fn predecessors_for(&self, bb: BasicBlock) -> &[BasicBlock] {
240+
self.cache.unwrap_predecessors_for(bb)
241+
}
242+
243+
#[inline]
244+
pub fn body(&self) -> &'a Body<'tcx> {
245+
self.body
246+
}
247+
248+
#[inline]
249+
pub fn basic_blocks(&self) -> &IndexVec<BasicBlock, BasicBlockData<'tcx>> {
250+
&self.body.basic_blocks
251+
}
252+
253+
#[inline]
254+
pub fn dominators(&self) -> Dominators<BasicBlock> {
255+
dominators(self)
256+
}
257+
258+
pub fn to_owned(self) -> BodyCache<&'a Body<'tcx>> {
259+
BodyCache {
260+
cache: self.cache,
261+
body: self.body,
262+
}
263+
}
264+
}
265+
266+
impl graph::DirectedGraph for ReadOnlyBodyCache<'a, 'tcx> {
267+
type Node = BasicBlock;
268+
}
269+
270+
impl graph::GraphPredecessors<'graph> for ReadOnlyBodyCache<'a, 'tcx> {
271+
type Item = BasicBlock;
272+
type Iter = IntoIter<BasicBlock>;
273+
}
274+
275+
impl graph::WithPredecessors for ReadOnlyBodyCache<'a, 'tcx> {
276+
fn predecessors(
277+
&self,
278+
node: Self::Node,
279+
) -> <Self as GraphPredecessors<'_>>::Iter {
280+
self.cache.unwrap_predecessors_for(node).to_vec().into_iter()
281+
}
282+
}
283+
284+
impl graph::WithNumNodes for ReadOnlyBodyCache<'a, 'tcx> {
285+
fn num_nodes(&self) -> usize {
286+
self.body.num_nodes()
287+
}
288+
}
289+
290+
impl graph::WithStartNode for ReadOnlyBodyCache<'a, 'tcx> {
291+
fn start_node(&self) -> Self::Node {
292+
self.body.start_node()
293+
}
294+
}
295+
296+
impl graph::WithSuccessors for ReadOnlyBodyCache<'a, 'tcx> {
297+
fn successors(
298+
&self,
299+
node: Self::Node,
300+
) -> <Self as GraphSuccessors<'_>>::Iter {
301+
self.body.successors(node)
302+
}
303+
}
304+
305+
impl<'a, 'b, 'tcx> graph::GraphSuccessors<'b> for ReadOnlyBodyCache<'a, 'tcx> {
306+
type Item = BasicBlock;
307+
type Iter = iter::Cloned<Successors<'b>>;
308+
}
309+
310+
311+
impl Deref for ReadOnlyBodyCache<'a, 'tcx> {
312+
type Target = Body<'tcx>;
313+
314+
fn deref(&self) -> &Self::Target {
315+
self.body
316+
}
317+
}
318+
319+
impl Index<BasicBlock> for ReadOnlyBodyCache<'a, 'tcx> {
320+
type Output = BasicBlockData<'tcx>;
321+
322+
#[inline]
323+
fn index(&self, index: BasicBlock) -> &BasicBlockData<'tcx> {
324+
&self.body[index]
325+
}
326+
}

src/librustc/mir/mod.rs

Lines changed: 2 additions & 2 deletions
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;
41+
pub use crate::mir::cache::{BodyCache, ReadOnlyBodyCache};
4242

4343
pub mod cache;
4444
pub mod interpret;
@@ -2600,7 +2600,7 @@ impl Location {
26002600
pub fn is_predecessor_of<'tcx>(
26012601
&self,
26022602
other: Location,
2603-
mut body_cache: BodyCache<&'_ Body<'tcx>>
2603+
body_cache: &ReadOnlyBodyCache<'_, 'tcx>
26042604
) -> bool {
26052605
// If we are in the same block as the other location and are an earlier statement
26062606
// then we are a predecessor of `other`.

src/librustc/mir/visit.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,15 @@ use syntax_pos::Span;
6565
// variant argument) that does not require visiting, as in
6666
// `is_cleanup` above.
6767

68+
macro_rules! body_cache_type {
69+
(mut $a:lifetime, $tcx:lifetime) => {
70+
&mut BodyCache<& $a mut Body<$tcx>>
71+
};
72+
($a:lifetime, $tcx:lifetime) => {
73+
&ReadOnlyBodyCache<$a, $tcx>
74+
};
75+
}
76+
6877
macro_rules! make_mir_visitor {
6978
($visitor_trait_name:ident, $($mutability:ident)?) => {
7079
pub trait $visitor_trait_name<'tcx> {
@@ -73,7 +82,7 @@ macro_rules! make_mir_visitor {
7382

7483
fn visit_body(
7584
&mut self,
76-
body_cache: & $($mutability)? BodyCache<&'_ $($mutability)? Body<'tcx>>
85+
body_cache: body_cache_type!($($mutability)? '_, 'tcx)
7786
) {
7887
self.super_body(body_cache);
7988
}
@@ -245,7 +254,7 @@ macro_rules! make_mir_visitor {
245254

246255
fn super_body(
247256
&mut self,
248-
body_cache: & $($mutability)? BodyCache<&'_ $($mutability)? Body<'tcx>>
257+
body_cache: body_cache_type!($($mutability)? '_, 'tcx)
249258
) {
250259
macro_rules! body {
251260
(mut) => (body_cache.body_mut());

src/librustc_codegen_ssa/mir/analyze.rs

Lines changed: 14 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
use rustc_index::bit_set::BitSet;
55
use rustc_data_structures::graph::dominators::Dominators;
66
use rustc_index::vec::{Idx, IndexVec};
7-
use rustc::mir::{self, Body, BodyCache, Location, TerminatorKind};
7+
use rustc::mir::{self, Location, TerminatorKind};
88
use rustc::mir::visit::{
99
Visitor, PlaceContext, MutatingUseContext, NonMutatingUseContext, NonUseContext,
1010
};
@@ -16,15 +16,14 @@ use syntax_pos::DUMMY_SP;
1616
use super::FunctionCx;
1717
use crate::traits::*;
1818

19-
pub fn non_ssa_locals<'a, 'b, 'c, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
20-
fx: &FunctionCx<'a, 'b, 'tcx, Bx>,
21-
mir: &'c mut BodyCache<&'b Body<'tcx>>,
19+
pub fn non_ssa_locals<'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
20+
fx: &FunctionCx<'a, 'b, 'tcx, Bx>
2221
) -> BitSet<mir::Local> {
23-
let mut analyzer = LocalAnalyzer::new(fx, mir);
22+
let mut analyzer = LocalAnalyzer::new(fx);
2423

25-
analyzer.visit_body(mir);
24+
analyzer.visit_body(fx.mir);
2625

27-
for (local, decl) in mir.local_decls.iter_enumerated()
26+
for (local, decl) in fx.mir.local_decls.iter_enumerated()
2827
{
2928
// FIXME(eddyb): We should figure out how to use llvm.dbg.value instead
3029
// of putting everything in allocas just so we can use llvm.dbg.declare.
@@ -66,20 +65,20 @@ struct LocalAnalyzer<'mir, 'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> {
6665
first_assignment: IndexVec<mir::Local, Location>,
6766
}
6867

69-
impl<'mir, 'a, 'b, 'c, 'tcx, Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'b, 'tcx, Bx> {
70-
fn new(fx: &'mir FunctionCx<'a, 'b, 'tcx, Bx>, mir: &'c mut BodyCache<&'b Body<'tcx>>) -> Self {
68+
impl<'mir, 'a, 'b, 'tcx, Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'b, 'tcx, Bx> {
69+
fn new(fx: &'mir FunctionCx<'a, 'b, 'tcx, Bx>) -> Self {
7170
let invalid_location =
72-
mir::BasicBlock::new(mir.basic_blocks().len()).start_location();
73-
let dominators = mir.dominators();
71+
mir::BasicBlock::new(fx.mir.basic_blocks().len()).start_location();
72+
let dominators = fx.mir.dominators();
7473
let mut analyzer = LocalAnalyzer {
7574
fx,
7675
dominators,
77-
non_ssa_locals: BitSet::new_empty(mir.local_decls.len()),
78-
first_assignment: IndexVec::from_elem(invalid_location, &mir.local_decls)
76+
non_ssa_locals: BitSet::new_empty(fx.mir.local_decls.len()),
77+
first_assignment: IndexVec::from_elem(invalid_location, &fx.mir.local_decls)
7978
};
8079

8180
// Arguments get assigned to by means of the function being called
82-
for arg in mir.args_iter() {
81+
for arg in fx.mir.args_iter() {
8382
analyzer.first_assignment[arg] = mir::START_BLOCK.start_location();
8483
}
8584

@@ -131,7 +130,7 @@ impl<'mir, 'a, 'b, 'c, 'tcx, Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, '
131130
};
132131
if is_consume {
133132
let base_ty =
134-
mir::Place::ty_from(place_ref.base, proj_base, self.fx.mir, cx.tcx());
133+
mir::Place::ty_from(place_ref.base, proj_base, self.fx.mir.body(), cx.tcx());
135134
let base_ty = self.fx.monomorphize(&base_ty);
136135

137136
// ZSTs don't require any actual memory access.

0 commit comments

Comments
 (0)