@@ -40,7 +40,8 @@ impl SsaLocals {
4040 let dominators = body. basic_blocks . dominators ( ) ;
4141
4242 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 } ;
4445
4546 for local in body. args_iter ( ) {
4647 visitor. assignments [ local] = Set1 :: One ( DefLocation :: Argument ) ;
@@ -110,7 +111,7 @@ impl SsaLocals {
110111 body : & ' a Body < ' tcx > ,
111112 ) -> impl Iterator < Item = ( Local , & ' a Rvalue < ' tcx > , Location ) > + ' a {
112113 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] {
114115 let stmt = body. stmt_at ( loc) . left ( ) ?;
115116 // `loc` must point to a direct assignment to `local`.
116117 let Some ( ( target, rvalue) ) = stmt. kind . as_assign ( ) else { bug ! ( ) } ;
@@ -134,21 +135,21 @@ impl SsaLocals {
134135 AssignedValue :: Arg ,
135136 Location { block : START_BLOCK , statement_index : 0 } ,
136137 ) ,
137- Set1 :: One ( DefLocation :: Body ( loc) ) => {
138+ Set1 :: One ( DefLocation :: Assignment ( loc) ) => {
138139 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 ! ( )
150144 } ;
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)
152153 }
153154 _ => { }
154155 }
@@ -201,14 +202,15 @@ impl SsaLocals {
201202 }
202203}
203204
204- struct SsaVisitor < ' a > {
205+ struct SsaVisitor < ' tcx , ' a > {
206+ body : & ' a Body < ' tcx > ,
205207 dominators : & ' a Dominators < BasicBlock > ,
206208 assignments : IndexVec < Local , Set1 < DefLocation > > ,
207209 assignment_order : Vec < Local > ,
208210 direct_uses : IndexVec < Local , u32 > ,
209211}
210212
211- impl SsaVisitor < ' _ > {
213+ impl SsaVisitor < ' _ , ' _ > {
212214 fn check_dominates ( & mut self , local : Local , loc : Location ) {
213215 let set = & mut self . assignments [ local] ;
214216 let assign_dominates = match * set {
@@ -224,7 +226,7 @@ impl SsaVisitor<'_> {
224226 }
225227}
226228
227- impl < ' tcx > Visitor < ' tcx > for SsaVisitor < ' _ > {
229+ impl < ' tcx > Visitor < ' tcx > for SsaVisitor < ' tcx , ' _ > {
228230 fn visit_local ( & mut self , local : Local , ctxt : PlaceContext , loc : Location ) {
229231 match ctxt {
230232 PlaceContext :: MutatingUse ( MutatingUseContext :: Projection )
@@ -250,9 +252,18 @@ impl<'tcx> Visitor<'tcx> for SsaVisitor<'_> {
250252
251253 fn visit_place ( & mut self , place : & Place < ' tcx > , ctxt : PlaceContext , loc : Location ) {
252254 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+ }
256267 _ => None ,
257268 } ;
258269 if let Some ( location) = location
@@ -359,7 +370,7 @@ impl StorageLiveLocals {
359370 for ( statement_index, statement) in bbdata. statements . iter ( ) . enumerate ( ) {
360371 if let StatementKind :: StorageLive ( local) = statement. kind {
361372 storage_live[ local]
362- . insert ( DefLocation :: Body ( Location { block, statement_index } ) ) ;
373+ . insert ( DefLocation :: Assignment ( Location { block, statement_index } ) ) ;
363374 }
364375 }
365376 }
0 commit comments