1
1
//! Inlining pass for MIR functions
2
2
3
3
use rustc_attr:: InlineAttr ;
4
- use rustc_hir as hir;
5
4
use rustc_index:: bit_set:: BitSet ;
6
5
use rustc_index:: vec:: Idx ;
7
6
use rustc_middle:: middle:: codegen_fn_attrs:: { CodegenFnAttrFlags , CodegenFnAttrs } ;
@@ -88,7 +87,6 @@ fn inline<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> bool {
88
87
tcx,
89
88
param_env,
90
89
codegen_fn_attrs : tcx. codegen_fn_attrs ( def_id) ,
91
- hir_id,
92
90
history : Vec :: new ( ) ,
93
91
changed : false ,
94
92
} ;
@@ -102,8 +100,6 @@ struct Inliner<'tcx> {
102
100
param_env : ParamEnv < ' tcx > ,
103
101
/// Caller codegen attributes.
104
102
codegen_fn_attrs : & ' tcx CodegenFnAttrs ,
105
- /// Caller HirID.
106
- hir_id : hir:: HirId ,
107
103
/// Stack of inlined Instances.
108
104
history : Vec < ty:: Instance < ' tcx > > ,
109
105
/// Indicates that the caller body has been modified.
@@ -179,7 +175,9 @@ impl<'tcx> Inliner<'tcx> {
179
175
caller_body : & Body < ' tcx > ,
180
176
callee : & Instance < ' tcx > ,
181
177
) -> Result < ( ) , & ' static str > {
182
- if callee. def_id ( ) == caller_body. source . def_id ( ) {
178
+ let caller_def_id = caller_body. source . def_id ( ) ;
179
+ let callee_def_id = callee. def_id ( ) ;
180
+ if callee_def_id == caller_def_id {
183
181
return Err ( "self-recursion" ) ;
184
182
}
185
183
@@ -188,7 +186,7 @@ impl<'tcx> Inliner<'tcx> {
188
186
// If there is no MIR available (either because it was not in metadata or
189
187
// because it has no MIR because it's an extern function), then the inliner
190
188
// won't cause cycles on this.
191
- if !self . tcx . is_mir_available ( callee . def_id ( ) ) {
189
+ if !self . tcx . is_mir_available ( callee_def_id ) {
192
190
return Err ( "item MIR unavailable" ) ;
193
191
}
194
192
}
@@ -208,29 +206,26 @@ impl<'tcx> Inliner<'tcx> {
208
206
| InstanceDef :: CloneShim ( ..) => return Ok ( ( ) ) ,
209
207
}
210
208
211
- if self . tcx . is_constructor ( callee . def_id ( ) ) {
209
+ if self . tcx . is_constructor ( callee_def_id ) {
212
210
trace ! ( "constructors always have MIR" ) ;
213
211
// Constructor functions cannot cause a query cycle.
214
212
return Ok ( ( ) ) ;
215
213
}
216
214
217
- if let Some ( callee_def_id) = callee. def_id ( ) . as_local ( ) {
218
- let callee_hir_id = self . tcx . hir ( ) . local_def_id_to_hir_id ( callee_def_id) ;
215
+ if callee_def_id. is_local ( ) {
219
216
// Avoid a cycle here by only using `instance_mir` only if we have
220
- // a lower `HirId` than the callee. This ensures that the callee will
221
- // not inline us. This trick only works without incremental compilation.
222
- // So don't do it if that is enabled.
223
- if !self . tcx . dep_graph . is_fully_enabled ( ) && self . hir_id . index ( ) < callee_hir_id. index ( )
217
+ // a lower `DefPathHash` than the callee. This ensures that the callee will
218
+ // not inline us. This trick even works with incremental compilation,
219
+ // since `DefPathHash` is stable.
220
+ if self . tcx . def_path_hash ( caller_def_id) . local_hash ( )
221
+ < self . tcx . def_path_hash ( callee_def_id) . local_hash ( )
224
222
{
225
223
return Ok ( ( ) ) ;
226
224
}
227
225
228
226
// If we know for sure that the function we're calling will itself try to
229
227
// call us, then we avoid inlining that function.
230
- if self
231
- . tcx
232
- . mir_callgraph_reachable ( ( * callee, caller_body. source . def_id ( ) . expect_local ( ) ) )
233
- {
228
+ if self . tcx . mir_callgraph_reachable ( ( * callee, caller_def_id. expect_local ( ) ) ) {
234
229
return Err ( "caller might be reachable from callee (query cycle avoidance)" ) ;
235
230
}
236
231
0 commit comments