@@ -23,11 +23,11 @@ use rustc_hir::def::{CtorKind, DefKind};
2323use rustc_hir:: def_id:: LocalDefId ;
2424use rustc_index:: IndexVec ;
2525use rustc_middle:: mir:: {
26- AnalysisPhase , Body , CallSource , ClearCrossCrate , ConstOperand , ConstQualifs , ConstValue ,
27- LocalDecl , MirPhase , Operand , Place , ProjectionElem , Promoted , RETURN_PLACE , RuntimePhase ,
28- Rvalue , START_BLOCK , SourceInfo , Statement , StatementKind , TerminatorKind ,
26+ AnalysisPhase , Body , CallSource , ClearCrossCrate , ConstOperand , ConstQualifs , LocalDecl ,
27+ MirPhase , Operand , Place , ProjectionElem , Promoted , RuntimePhase , Rvalue , START_BLOCK ,
28+ SourceInfo , Statement , StatementKind , TerminatorKind ,
2929} ;
30- use rustc_middle:: ty:: { self , Ty , TyCtxt , TypeVisitableExt } ;
30+ use rustc_middle:: ty:: { self , TyCtxt , TypeVisitableExt } ;
3131use rustc_middle:: util:: Providers ;
3232use rustc_middle:: { bug, query, span_bug} ;
3333use rustc_mir_build:: builder:: build_mir;
@@ -55,6 +55,7 @@ mod liveness;
5555mod patch;
5656mod shim;
5757mod ssa;
58+ mod trivial_const;
5859
5960/// We import passes via this macro so that we can have a static list of pass names
6061/// (used to verify CLI arguments). It takes a list of modules, followed by the passes
@@ -226,7 +227,7 @@ pub fn provide(providers: &mut Providers) {
226227 promoted_mir,
227228 deduced_param_attrs : deduce_param_attrs:: deduced_param_attrs,
228229 coroutine_by_move_body_def_id : coroutine:: coroutine_by_move_body_def_id,
229- trivial_const : trivial_const_provider,
230+ trivial_const : trivial_const :: trivial_const_provider,
230231 ..providers. queries
231232 } ;
232233}
@@ -377,66 +378,14 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def: LocalDefId) -> ConstQualifs {
377378 validator. qualifs_in_return_place ( )
378379}
379380
380- fn def_kind_compatible_with_trivial_mir < ' tcx > ( tcx : TyCtxt < ' tcx > , def : LocalDefId ) -> bool {
381- // Static and InlineConst are the obvious additions, but
382- // * Statics need additional type-checking to taint `static A: _ = 0;`, currently we'd ICE.
383- // * The MIR for InlineConst is used by the borrow checker, and not easy to skip over.
384- matches ! ( tcx. def_kind( def) , DefKind :: AssocConst | DefKind :: Const | DefKind :: AnonConst )
385- }
386-
387- fn trivial_const_provider < ' tcx > (
388- tcx : TyCtxt < ' tcx > ,
389- def : LocalDefId ,
390- ) -> Option < ( ConstValue , Ty < ' tcx > ) > {
391- if def_kind_compatible_with_trivial_mir ( tcx, def) {
392- trivial_const ( & tcx. mir_built ( def) . borrow ( ) )
393- } else {
394- None
395- }
396- }
397-
398- fn trivial_const < ' tcx > ( body : & Body < ' tcx > ) -> Option < ( ConstValue , Ty < ' tcx > ) > {
399- if body. has_opaque_types ( ) {
400- return None ;
401- }
402-
403- if body. basic_blocks . len ( ) != 1 {
404- return None ;
405- }
406-
407- let block = & body. basic_blocks [ START_BLOCK ] ;
408- if block. statements . len ( ) != 1 {
409- return None ;
410- }
411-
412- if block. terminator ( ) . kind != TerminatorKind :: Return {
413- return None ;
414- }
415-
416- let StatementKind :: Assign ( box ( place, rvalue) ) = & block. statements [ 0 ] . kind else {
417- return None ;
418- } ;
419-
420- if * place != Place :: from ( RETURN_PLACE ) {
421- return None ;
422- }
423-
424- if let Rvalue :: Use ( Operand :: Constant ( c) ) = rvalue {
425- if let rustc_middle:: mir:: Const :: Val ( v, ty) = c. const_ {
426- return Some ( ( v, ty) ) ;
427- }
428- }
429-
430- return None ;
431- }
432-
433381fn mir_built ( tcx : TyCtxt < ' _ > , def : LocalDefId ) -> & Steal < Body < ' _ > > {
434382 let mut body = build_mir ( tcx, def) ;
435383
436384 // Identifying trivial consts based on their mir_built is easy, but a little wasteful.
437385 // Trying to push this logic earlier in the compiler and never even produce the Body would
438386 // probably improve compile time.
439- if def_kind_compatible_with_trivial_mir ( tcx, def) && trivial_const ( & body) . is_some ( ) {
387+ if trivial_const:: trivial_const ( tcx, def, || & body) . is_some ( ) {
388+ // Skip all the passes below for trivial consts.
440389 let body = tcx. alloc_steal_mir ( body) ;
441390 pass_manager:: dump_mir_for_phase_change ( tcx, & body. borrow ( ) ) ;
442391 return body;
0 commit comments