@@ -17,6 +17,8 @@ use mir::repr::Mir;
17
17
use ty:: TyCtxt ;
18
18
use syntax:: ast:: NodeId ;
19
19
20
+ use std:: fmt;
21
+
20
22
/// Where a specific Mir comes from.
21
23
#[ derive( Debug , Copy , Clone ) ]
22
24
pub enum MirSource {
@@ -70,16 +72,32 @@ impl<'a, 'tcx> MirSource {
70
72
71
73
/// Various information about pass.
72
74
pub trait Pass {
73
- // fn name() for printouts of various sorts?
74
75
// fn should_run(Session) to check if pass should run?
75
76
fn dep_node ( & self , def_id : DefId ) -> DepNode < DefId > {
76
77
DepNode :: MirPass ( def_id)
77
78
}
79
+ fn name ( & self ) -> & str ;
80
+ fn disambiguator < ' a > ( & ' a self ) -> Option < Box < fmt:: Display +' a > > { None }
78
81
}
79
82
80
83
/// A pass which inspects the whole MirMap.
81
84
pub trait MirMapPass < ' tcx > : Pass {
82
- fn run_pass < ' a > ( & mut self , tcx : TyCtxt < ' a , ' tcx , ' tcx > , map : & mut MirMap < ' tcx > ) ;
85
+ fn run_pass < ' a > (
86
+ & mut self ,
87
+ tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
88
+ map : & mut MirMap < ' tcx > ,
89
+ hooks : & mut [ Box <for <' s > MirPassHook < ' s > >] ) ;
90
+ }
91
+
92
+ pub trait MirPassHook < ' tcx > : Pass {
93
+ fn on_mir_pass < ' a > (
94
+ & mut self ,
95
+ tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
96
+ src : MirSource ,
97
+ mir : & Mir < ' tcx > ,
98
+ pass : & Pass ,
99
+ is_after : bool
100
+ ) ;
83
101
}
84
102
85
103
/// A pass which inspects Mir of functions in isolation.
@@ -94,16 +112,33 @@ pub trait MirPass<'tcx>: Pass {
94
112
}
95
113
96
114
impl < ' tcx , T : MirPass < ' tcx > > MirMapPass < ' tcx > for T {
97
- fn run_pass < ' a > ( & mut self , tcx : TyCtxt < ' a , ' tcx , ' tcx > , map : & mut MirMap < ' tcx > ) {
115
+ fn run_pass < ' a > ( & mut self ,
116
+ tcx : TyCtxt < ' a , ' tcx , ' tcx > ,
117
+ map : & mut MirMap < ' tcx > ,
118
+ hooks : & mut [ Box <for <' s > MirPassHook < ' s > >] )
119
+ {
98
120
for ( & id, mir) in & mut map. map {
99
121
let def_id = tcx. map . local_def_id ( id) ;
100
122
let _task = tcx. dep_graph . in_task ( self . dep_node ( def_id) ) ;
101
123
102
124
let src = MirSource :: from_node ( tcx, id) ;
125
+
126
+ for hook in & mut * hooks {
127
+ hook. on_mir_pass ( tcx, src, mir, self , false ) ;
128
+ }
103
129
MirPass :: run_pass ( self , tcx, src, mir) ;
130
+ for hook in & mut * hooks {
131
+ hook. on_mir_pass ( tcx, src, mir, self , true ) ;
132
+ }
104
133
105
134
for ( i, mir) in mir. promoted . iter_mut ( ) . enumerate ( ) {
135
+ for hook in & mut * hooks {
136
+ hook. on_mir_pass ( tcx, src, mir, self , false ) ;
137
+ }
106
138
self . run_pass_on_promoted ( tcx, id, i, mir) ;
139
+ for hook in & mut * hooks {
140
+ hook. on_mir_pass ( tcx, src, mir, self , true ) ;
141
+ }
107
142
}
108
143
}
109
144
}
@@ -112,31 +147,38 @@ impl<'tcx, T: MirPass<'tcx>> MirMapPass<'tcx> for T {
112
147
/// A manager for MIR passes.
113
148
pub struct Passes {
114
149
passes : Vec < Box <for <' tcx > MirMapPass < ' tcx > >> ,
150
+ pass_hooks : Vec < Box <for <' tcx > MirPassHook < ' tcx > >> ,
115
151
plugin_passes : Vec < Box <for <' tcx > MirMapPass < ' tcx > >>
116
152
}
117
153
118
154
impl < ' a , ' tcx > Passes {
119
155
pub fn new ( ) -> Passes {
120
156
let passes = Passes {
121
157
passes : Vec :: new ( ) ,
158
+ pass_hooks : Vec :: new ( ) ,
122
159
plugin_passes : Vec :: new ( )
123
160
} ;
124
161
passes
125
162
}
126
163
127
164
pub fn run_passes ( & mut self , tcx : TyCtxt < ' a , ' tcx , ' tcx > , map : & mut MirMap < ' tcx > ) {
128
165
for pass in & mut self . plugin_passes {
129
- pass. run_pass ( tcx, map) ;
166
+ pass. run_pass ( tcx, map, & mut self . pass_hooks ) ;
130
167
}
131
168
for pass in & mut self . passes {
132
- pass. run_pass ( tcx, map) ;
169
+ pass. run_pass ( tcx, map, & mut self . pass_hooks ) ;
133
170
}
134
171
}
135
172
136
173
/// Pushes a built-in pass.
137
174
pub fn push_pass ( & mut self , pass : Box <for <' b > MirMapPass < ' b > >) {
138
175
self . passes . push ( pass) ;
139
176
}
177
+
178
+ /// Pushes a pass hook.
179
+ pub fn push_hook ( & mut self , hook : Box <for <' b > MirPassHook < ' b > >) {
180
+ self . pass_hooks . push ( hook) ;
181
+ }
140
182
}
141
183
142
184
/// Copies the plugin passes.
0 commit comments