@@ -47,8 +47,7 @@ impl Cache {
47
47
}
48
48
49
49
#[ 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 < ' _ > ) {
52
51
if self . predecessors . is_none ( ) {
53
52
let mut result = IndexVec :: from_elem ( vec ! [ ] , body. basic_blocks ( ) ) ;
54
53
for ( bb, data) in body. basic_blocks ( ) . iter_enumerated ( ) {
@@ -61,7 +60,12 @@ impl Cache {
61
60
62
61
self . predecessors = Some ( result)
63
62
}
63
+ }
64
64
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) ;
65
69
self . predecessors . as_ref ( ) . unwrap ( )
66
70
}
67
71
@@ -70,6 +74,11 @@ impl Cache {
70
74
& self . predecessors ( body) [ bb]
71
75
}
72
76
77
+ #[ inline]
78
+ fn unwrap_predecessors_for ( & self , bb : BasicBlock ) -> & [ BasicBlock ] {
79
+ & self . predecessors . as_ref ( ) . unwrap ( ) [ bb]
80
+ }
81
+
73
82
#[ inline]
74
83
pub fn predecessor_locations < ' a > ( & ' a mut self , loc : Location , body : & ' a Body < ' a > ) -> impl Iterator < Item = Location > + ' a {
75
84
let if_zero_locations = if loc. statement_index == 0 {
@@ -137,13 +146,17 @@ impl<'a, 'tcx> BodyCache<&'a Body<'tcx>> {
137
146
}
138
147
139
148
#[ 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
+ }
142
155
}
143
156
144
157
#[ 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
147
160
}
148
161
}
149
162
@@ -164,50 +177,6 @@ impl<'a, 'tcx> Index<BasicBlock> for BodyCache<&'a Body<'tcx>> {
164
177
}
165
178
}
166
179
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
-
211
180
impl < ' a , ' tcx > BodyCache < & ' a mut Body < ' tcx > > {
212
181
#[ inline]
213
182
pub fn body ( & self ) -> & Body < ' tcx > {
@@ -259,3 +228,99 @@ impl<'a, 'tcx> IndexMut<BasicBlock> for BodyCache<&'a mut Body<'tcx>> {
259
228
& mut self . body . basic_blocks [ index]
260
229
}
261
230
}
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
+ }
0 commit comments