@@ -40,7 +40,8 @@ impl SsaLocals {
40
40
let dominators = body. basic_blocks . dominators ( ) ;
41
41
42
42
let direct_uses = IndexVec :: from_elem ( 0 , & body. local_decls ) ;
43
- let mut visitor = SsaVisitor { assignments, assignment_order, dominators, direct_uses } ;
43
+ let mut visitor =
44
+ SsaVisitor { body, assignments, assignment_order, dominators, direct_uses } ;
44
45
45
46
for local in body. args_iter ( ) {
46
47
visitor. assignments [ local] = Set1 :: One ( DefLocation :: Argument ) ;
@@ -110,7 +111,7 @@ impl SsaLocals {
110
111
body : & ' a Body < ' tcx > ,
111
112
) -> impl Iterator < Item = ( Local , & ' a Rvalue < ' tcx > , Location ) > + ' a {
112
113
self . assignment_order . iter ( ) . filter_map ( |& local| {
113
- if let Set1 :: One ( DefLocation :: Body ( loc) ) = self . assignments [ local] {
114
+ if let Set1 :: One ( DefLocation :: Assignment ( loc) ) = self . assignments [ local] {
114
115
let stmt = body. stmt_at ( loc) . left ( ) ?;
115
116
// `loc` must point to a direct assignment to `local`.
116
117
let Some ( ( target, rvalue) ) = stmt. kind . as_assign ( ) else { bug ! ( ) } ;
@@ -134,21 +135,21 @@ impl SsaLocals {
134
135
AssignedValue :: Arg ,
135
136
Location { block : START_BLOCK , statement_index : 0 } ,
136
137
) ,
137
- Set1 :: One ( DefLocation :: Body ( loc) ) => {
138
+ Set1 :: One ( DefLocation :: Assignment ( loc) ) => {
138
139
let bb = & mut basic_blocks[ loc. block ] ;
139
- let value = if loc. statement_index < bb. statements . len ( ) {
140
- // `loc` must point to a direct assignment to `local`.
141
- let stmt = & mut bb. statements [ loc. statement_index ] ;
142
- let StatementKind :: Assign ( box ( target, ref mut rvalue) ) = stmt. kind else {
143
- bug ! ( )
144
- } ;
145
- assert_eq ! ( target. as_local( ) , Some ( local) ) ;
146
- AssignedValue :: Rvalue ( rvalue)
147
- } else {
148
- let term = bb. terminator_mut ( ) ;
149
- AssignedValue :: Terminator ( & mut term. kind )
140
+ // `loc` must point to a direct assignment to `local`.
141
+ let stmt = & mut bb. statements [ loc. statement_index ] ;
142
+ let StatementKind :: Assign ( box ( target, ref mut rvalue) ) = stmt. kind else {
143
+ bug ! ( )
150
144
} ;
151
- f ( local, value, loc)
145
+ assert_eq ! ( target. as_local( ) , Some ( local) ) ;
146
+ f ( local, AssignedValue :: Rvalue ( rvalue) , loc)
147
+ }
148
+ Set1 :: One ( DefLocation :: CallReturn { call, .. } ) => {
149
+ let bb = & mut basic_blocks[ call] ;
150
+ let loc = Location { block : call, statement_index : bb. statements . len ( ) } ;
151
+ let term = bb. terminator_mut ( ) ;
152
+ f ( local, AssignedValue :: Terminator ( & mut term. kind ) , loc)
152
153
}
153
154
_ => { }
154
155
}
@@ -201,14 +202,15 @@ impl SsaLocals {
201
202
}
202
203
}
203
204
204
- struct SsaVisitor < ' a > {
205
+ struct SsaVisitor < ' tcx , ' a > {
206
+ body : & ' a Body < ' tcx > ,
205
207
dominators : & ' a Dominators < BasicBlock > ,
206
208
assignments : IndexVec < Local , Set1 < DefLocation > > ,
207
209
assignment_order : Vec < Local > ,
208
210
direct_uses : IndexVec < Local , u32 > ,
209
211
}
210
212
211
- impl SsaVisitor < ' _ > {
213
+ impl SsaVisitor < ' _ , ' _ > {
212
214
fn check_dominates ( & mut self , local : Local , loc : Location ) {
213
215
let set = & mut self . assignments [ local] ;
214
216
let assign_dominates = match * set {
@@ -224,7 +226,7 @@ impl SsaVisitor<'_> {
224
226
}
225
227
}
226
228
227
- impl < ' tcx > Visitor < ' tcx > for SsaVisitor < ' _ > {
229
+ impl < ' tcx > Visitor < ' tcx > for SsaVisitor < ' tcx , ' _ > {
228
230
fn visit_local ( & mut self , local : Local , ctxt : PlaceContext , loc : Location ) {
229
231
match ctxt {
230
232
PlaceContext :: MutatingUse ( MutatingUseContext :: Projection )
@@ -250,9 +252,18 @@ impl<'tcx> Visitor<'tcx> for SsaVisitor<'_> {
250
252
251
253
fn visit_place ( & mut self , place : & Place < ' tcx > , ctxt : PlaceContext , loc : Location ) {
252
254
let location = match ctxt {
253
- PlaceContext :: MutatingUse (
254
- MutatingUseContext :: Store | MutatingUseContext :: Call | MutatingUseContext :: Yield ,
255
- ) => Some ( DefLocation :: Body ( loc) ) ,
255
+ PlaceContext :: MutatingUse ( MutatingUseContext :: Store ) => {
256
+ Some ( DefLocation :: Assignment ( loc) )
257
+ }
258
+ PlaceContext :: MutatingUse ( MutatingUseContext :: Call ) => {
259
+ let call = loc. block ;
260
+ let TerminatorKind :: Call { target, .. } =
261
+ self . body . basic_blocks [ call] . terminator ( ) . kind
262
+ else {
263
+ bug ! ( )
264
+ } ;
265
+ Some ( DefLocation :: CallReturn { call, target } )
266
+ }
256
267
_ => None ,
257
268
} ;
258
269
if let Some ( location) = location
@@ -359,7 +370,7 @@ impl StorageLiveLocals {
359
370
for ( statement_index, statement) in bbdata. statements . iter ( ) . enumerate ( ) {
360
371
if let StatementKind :: StorageLive ( local) = statement. kind {
361
372
storage_live[ local]
362
- . insert ( DefLocation :: Body ( Location { block, statement_index } ) ) ;
373
+ . insert ( DefLocation :: Assignment ( Location { block, statement_index } ) ) ;
363
374
}
364
375
}
365
376
}
0 commit comments