@@ -10,13 +10,12 @@ use rustc_hir::def_id::DefId;
1010use rustc_index:: Idx ;
1111use rustc_index:: bit_set:: BitSet ;
1212use rustc_middle:: bug;
13- use rustc_middle:: middle:: codegen_fn_attrs:: { CodegenFnAttrFlags , CodegenFnAttrs } ;
13+ use rustc_middle:: middle:: codegen_fn_attrs:: CodegenFnAttrs ;
1414use rustc_middle:: mir:: visit:: * ;
1515use rustc_middle:: mir:: * ;
1616use rustc_middle:: ty:: { self , Instance , InstanceKind , Ty , TyCtxt , TypeFlags , TypeVisitableExt } ;
1717use rustc_session:: config:: { DebugInfo , OptLevel } ;
1818use rustc_span:: source_map:: Spanned ;
19- use rustc_span:: sym;
2019use tracing:: { debug, instrument, trace, trace_span} ;
2120
2221use crate :: cost_checker:: CostChecker ;
@@ -120,7 +119,6 @@ trait Inliner<'tcx> {
120119 callsite : & CallSite < ' tcx > ,
121120 callee_body : & Body < ' tcx > ,
122121 callee_attrs : & CodegenFnAttrs ,
123- cross_crate_inlinable : bool ,
124122 ) -> Result < ( ) , & ' static str > ;
125123
126124 // How many callsites in a body are we allowed to inline? We need to limit this in order
@@ -196,7 +194,6 @@ impl<'tcx> Inliner<'tcx> for ForceInliner<'tcx> {
196194 _: & CallSite < ' tcx > ,
197195 callee_body : & Body < ' tcx > ,
198196 callee_attrs : & CodegenFnAttrs ,
199- _: bool ,
200197 ) -> Result < ( ) , & ' static str > {
201198 if callee_body. tainted_by_errors . is_some ( ) {
202199 return Err ( "body has errors" ) ;
@@ -215,14 +212,6 @@ impl<'tcx> Inliner<'tcx> for ForceInliner<'tcx> {
215212 // inline-asm is detected. LLVM will still possibly do an inline later on
216213 // if the no-attribute function ends up with the same instruction set anyway.
217214 Err ( "cannot move inline-asm across instruction sets" )
218- } else if callee_body
219- . basic_blocks
220- . iter ( )
221- . any ( |bb| matches ! ( bb. terminator( ) . kind, TerminatorKind :: TailCall { .. } ) )
222- {
223- // FIXME(explicit_tail_calls): figure out how exactly functions containing tail
224- // calls can be inlined (and if they even should)
225- Err ( "can't inline functions with tail calls" )
226215 } else {
227216 Ok ( ( ) )
228217 }
@@ -348,7 +337,6 @@ impl<'tcx> Inliner<'tcx> for NormalInliner<'tcx> {
348337 callsite : & CallSite < ' tcx > ,
349338 callee_body : & Body < ' tcx > ,
350339 callee_attrs : & CodegenFnAttrs ,
351- cross_crate_inlinable : bool ,
352340 ) -> Result < ( ) , & ' static str > {
353341 let tcx = self . tcx ( ) ;
354342
@@ -358,7 +346,7 @@ impl<'tcx> Inliner<'tcx> for NormalInliner<'tcx> {
358346
359347 let mut threshold = if self . caller_is_inline_forwarder {
360348 tcx. sess . opts . unstable_opts . inline_mir_forwarder_threshold . unwrap_or ( 30 )
361- } else if cross_crate_inlinable {
349+ } else if tcx . cross_crate_inlinable ( callsite . callee . def_id ( ) ) {
362350 tcx. sess . opts . unstable_opts . inline_mir_hint_threshold . unwrap_or ( 100 )
363351 } else {
364352 tcx. sess . opts . unstable_opts . inline_mir_threshold . unwrap_or ( 50 )
@@ -587,16 +575,8 @@ fn try_inlining<'tcx, I: Inliner<'tcx>>(
587575 check_mir_is_available ( inliner, caller_body, callsite. callee ) ?;
588576
589577 let callee_attrs = tcx. codegen_fn_attrs ( callsite. callee . def_id ( ) ) ;
590- let cross_crate_inlinable = tcx. cross_crate_inlinable ( callsite. callee . def_id ( ) ) ;
591- check_codegen_attributes ( inliner, callsite, callee_attrs, cross_crate_inlinable) ?;
592-
593- // Intrinsic fallback bodies are automatically made cross-crate inlineable,
594- // but at this stage we don't know whether codegen knows the intrinsic,
595- // so just conservatively don't inline it. This also ensures that we do not
596- // accidentally inline the body of an intrinsic that *must* be overridden.
597- if tcx. has_attr ( callsite. callee . def_id ( ) , sym:: rustc_intrinsic) {
598- return Err ( "callee is an intrinsic" ) ;
599- }
578+ rustc_mir_build:: check_inline:: is_inline_valid_on_fn ( tcx, callsite. callee . def_id ( ) ) ?;
579+ check_codegen_attributes ( inliner, callsite, callee_attrs) ?;
600580
601581 let terminator = caller_body[ callsite. block ] . terminator . as_ref ( ) . unwrap ( ) ;
602582 let TerminatorKind :: Call { args, destination, .. } = & terminator. kind else { bug ! ( ) } ;
@@ -610,7 +590,8 @@ fn try_inlining<'tcx, I: Inliner<'tcx>>(
610590 }
611591
612592 let callee_body = try_instance_mir ( tcx, callsite. callee . def ) ?;
613- inliner. check_callee_mir_body ( callsite, callee_body, callee_attrs, cross_crate_inlinable) ?;
593+ rustc_mir_build:: check_inline:: is_inline_valid_on_body ( tcx, callee_body) ?;
594+ inliner. check_callee_mir_body ( callsite, callee_body, callee_attrs) ?;
614595
615596 let Ok ( callee_body) = callsite. callee . try_instantiate_mir_and_normalize_erasing_regions (
616597 tcx,
@@ -775,38 +756,19 @@ fn check_codegen_attributes<'tcx, I: Inliner<'tcx>>(
775756 inliner : & I ,
776757 callsite : & CallSite < ' tcx > ,
777758 callee_attrs : & CodegenFnAttrs ,
778- cross_crate_inlinable : bool ,
779759) -> Result < ( ) , & ' static str > {
780760 let tcx = inliner. tcx ( ) ;
781- if tcx. has_attr ( callsite. callee . def_id ( ) , sym:: rustc_no_mir_inline) {
782- return Err ( "#[rustc_no_mir_inline]" ) ;
783- }
784-
785761 if let InlineAttr :: Never = callee_attrs. inline {
786762 return Err ( "never inline attribute" ) ;
787763 }
788764
789- // FIXME(#127234): Coverage instrumentation currently doesn't handle inlined
790- // MIR correctly when Modified Condition/Decision Coverage is enabled.
791- if tcx. sess . instrument_coverage_mcdc ( ) {
792- return Err ( "incompatible with MC/DC coverage" ) ;
793- }
794-
795765 // Reachability pass defines which functions are eligible for inlining. Generally inlining
796766 // other functions is incorrect because they could reference symbols that aren't exported.
797767 let is_generic = callsite. callee . args . non_erasable_generics ( ) . next ( ) . is_some ( ) ;
798- if !is_generic && !cross_crate_inlinable {
768+ if !is_generic && !tcx . cross_crate_inlinable ( callsite . callee . def_id ( ) ) {
799769 return Err ( "not exported" ) ;
800770 }
801771
802- if callsite. fn_sig . c_variadic ( ) {
803- return Err ( "C variadic" ) ;
804- }
805-
806- if callee_attrs. flags . contains ( CodegenFnAttrFlags :: COLD ) {
807- return Err ( "cold" ) ;
808- }
809-
810772 let codegen_fn_attrs = tcx. codegen_fn_attrs ( inliner. caller_def_id ( ) ) ;
811773 if callee_attrs. no_sanitize != codegen_fn_attrs. no_sanitize {
812774 return Err ( "incompatible sanitizer set" ) ;
0 commit comments