@@ -19,7 +19,7 @@ use rustc_data_structures::indexed_vec::{Idx, IndexVec};
1919
2020use rustc:: mir:: * ;
2121use rustc:: mir:: visit:: * ;
22- use rustc:: ty:: { self , Instance , InstanceDef , Ty , TyCtxt } ;
22+ use rustc:: ty:: { self , Instance , InstanceDef , ParamEnv , Ty , TyCtxt } ;
2323use rustc:: ty:: subst:: { Subst , Substs } ;
2424
2525use std:: collections:: VecDeque ;
@@ -85,39 +85,16 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
8585 // Only do inlining into fn bodies.
8686 let id = self . tcx . hir . as_local_node_id ( self . source . def_id ) . unwrap ( ) ;
8787 let body_owner_kind = self . tcx . hir . body_owner_kind ( id) ;
88+
8889 if let ( hir:: BodyOwnerKind :: Fn , None ) = ( body_owner_kind, self . source . promoted ) {
8990
9091 for ( bb, bb_data) in caller_mir. basic_blocks ( ) . iter_enumerated ( ) {
91- // Don't inline calls that are in cleanup blocks.
92- if bb_data. is_cleanup { continue ; }
93-
94- // Only consider direct calls to functions
95- let terminator = bb_data. terminator ( ) ;
96- if let TerminatorKind :: Call {
97- func : ref op, .. } = terminator. kind {
98- if let ty:: FnDef ( callee_def_id, substs) = op. ty ( caller_mir, self . tcx ) . sty {
99- if let Some ( instance) = Instance :: resolve ( self . tcx ,
100- param_env,
101- callee_def_id,
102- substs) {
103- let is_virtual =
104- if let InstanceDef :: Virtual ( ..) = instance. def {
105- true
106- } else {
107- false
108- } ;
109-
110- if !is_virtual {
111- callsites. push_back ( CallSite {
112- callee : instance. def_id ( ) ,
113- substs : instance. substs ,
114- bb,
115- location : terminator. source_info
116- } ) ;
117- }
118- }
119- }
120- }
92+ if let Some ( callsite) = self . get_valid_function_call ( bb,
93+ bb_data,
94+ caller_mir,
95+ param_env) {
96+ callsites. push_back ( callsite) ;
97+ }
12198 }
12299 } else {
123100 return ;
@@ -163,20 +140,13 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
163140
164141 // Add callsites from inlined function
165142 for ( bb, bb_data) in caller_mir. basic_blocks ( ) . iter_enumerated ( ) . skip ( start) {
166- // Only consider direct calls to functions
167- let terminator = bb_data. terminator ( ) ;
168- if let TerminatorKind :: Call {
169- func : Operand :: Constant ( ref f) , .. } = terminator. kind {
170- if let ty:: FnDef ( callee_def_id, substs) = f. ty . sty {
171- // Don't inline the same function multiple times.
172- if callsite. callee != callee_def_id {
173- callsites. push_back ( CallSite {
174- callee : callee_def_id,
175- substs,
176- bb,
177- location : terminator. source_info
178- } ) ;
179- }
143+ if let Some ( new_callsite) = self . get_valid_function_call ( bb,
144+ bb_data,
145+ caller_mir,
146+ param_env) {
147+ // Don't inline the same function multiple times.
148+ if callsite. callee != new_callsite. callee {
149+ callsites. push_back ( new_callsite) ;
180150 }
181151 }
182152 }
@@ -198,6 +168,40 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
198168 }
199169 }
200170
171+ fn get_valid_function_call ( & self ,
172+ bb : BasicBlock ,
173+ bb_data : & BasicBlockData < ' tcx > ,
174+ caller_mir : & Mir < ' tcx > ,
175+ param_env : ParamEnv < ' tcx > ,
176+ ) -> Option < CallSite < ' tcx > > {
177+ // Don't inline calls that are in cleanup blocks.
178+ if bb_data. is_cleanup { return None ; }
179+
180+ // Only consider direct calls to functions
181+ let terminator = bb_data. terminator ( ) ;
182+ if let TerminatorKind :: Call { func : ref op, .. } = terminator. kind {
183+ if let ty:: FnDef ( callee_def_id, substs) = op. ty ( caller_mir, self . tcx ) . sty {
184+ let instance = Instance :: resolve ( self . tcx ,
185+ param_env,
186+ callee_def_id,
187+ substs) ?;
188+
189+ if let InstanceDef :: Virtual ( ..) = instance. def {
190+ return None ;
191+ }
192+
193+ return Some ( CallSite {
194+ callee : instance. def_id ( ) ,
195+ substs : instance. substs ,
196+ bb,
197+ location : terminator. source_info
198+ } ) ;
199+ }
200+ }
201+
202+ None
203+ }
204+
201205 fn consider_optimizing ( & self ,
202206 callsite : CallSite < ' tcx > ,
203207 callee_mir : & Mir < ' tcx > )
0 commit comments