@@ -16,7 +16,7 @@ use rustc_hir as hir;
16
16
use rustc_hir:: def_id:: DefId ;
17
17
use rustc_llvm:: RustString ;
18
18
use rustc_middle:: bug;
19
- use rustc_middle:: mir:: coverage:: { CodeRegion , CounterId , CoverageKind , ExpressionId , Op , Operand } ;
19
+ use rustc_middle:: mir:: coverage:: { CounterId , CoverageKind } ;
20
20
use rustc_middle:: mir:: Coverage ;
21
21
use rustc_middle:: ty;
22
22
use rustc_middle:: ty:: layout:: { FnAbiOf , HasTyCtxt } ;
@@ -104,144 +104,67 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
104
104
fn add_coverage ( & mut self , instance : Instance < ' tcx > , coverage : & Coverage ) {
105
105
let bx = self ;
106
106
107
+ let Some ( coverage_context) = bx. coverage_context ( ) else { return } ;
108
+ let mut coverage_map = coverage_context. function_coverage_map . borrow_mut ( ) ;
109
+ let func_coverage = coverage_map
110
+ . entry ( instance)
111
+ . or_insert_with ( || FunctionCoverage :: new ( bx. tcx ( ) , instance) ) ;
112
+
107
113
let Coverage { kind, code_region } = coverage. clone ( ) ;
108
114
match kind {
109
115
CoverageKind :: Counter { function_source_hash, id } => {
110
- if bx. set_function_source_hash ( instance, function_source_hash) {
111
- // If `set_function_source_hash()` returned true, the coverage map is enabled,
112
- // so continue adding the counter.
113
- if let Some ( code_region) = code_region {
114
- // Note: Some counters do not have code regions, but may still be referenced
115
- // from expressions. In that case, don't add the counter to the coverage map,
116
- // but do inject the counter intrinsic.
117
- bx. add_coverage_counter ( instance, id, code_region) ;
118
- }
119
-
120
- let coverageinfo = bx. tcx ( ) . coverageinfo ( instance. def ) ;
121
-
122
- let fn_name = bx. get_pgo_func_name_var ( instance) ;
123
- let hash = bx. const_u64 ( function_source_hash) ;
124
- let num_counters = bx. const_u32 ( coverageinfo. num_counters ) ;
125
- let index = bx. const_u32 ( id. as_u32 ( ) ) ;
116
+ debug ! (
117
+ "ensuring function source hash is set for instance={:?}; function_source_hash={}" ,
118
+ instance, function_source_hash,
119
+ ) ;
120
+ func_coverage. set_function_source_hash ( function_source_hash) ;
121
+
122
+ if let Some ( code_region) = code_region {
123
+ // Note: Some counters do not have code regions, but may still be referenced
124
+ // from expressions. In that case, don't add the counter to the coverage map,
125
+ // but do inject the counter intrinsic.
126
126
debug ! (
127
- "codegen intrinsic instrprof.increment(fn_name={:?}, hash ={:?}, num_counters ={:?}, index ={:?}) " ,
128
- fn_name , hash , num_counters , index ,
127
+ "adding counter to coverage_map: instance ={:?}, id ={:?}, region ={:?}" ,
128
+ instance , id , code_region ,
129
129
) ;
130
- bx . instrprof_increment ( fn_name , hash , num_counters , index ) ;
130
+ func_coverage . add_counter ( id , code_region ) ;
131
131
}
132
+ // We need to explicitly drop the `RefMut` before calling into `instrprof_increment`,
133
+ // as that needs an exclusive borrow.
134
+ drop ( coverage_map) ;
135
+
136
+ let coverageinfo = bx. tcx ( ) . coverageinfo ( instance. def ) ;
137
+
138
+ let fn_name = bx. get_pgo_func_name_var ( instance) ;
139
+ let hash = bx. const_u64 ( function_source_hash) ;
140
+ let num_counters = bx. const_u32 ( coverageinfo. num_counters ) ;
141
+ let index = bx. const_u32 ( id. as_u32 ( ) ) ;
142
+ debug ! (
143
+ "codegen intrinsic instrprof.increment(fn_name={:?}, hash={:?}, num_counters={:?}, index={:?})" ,
144
+ fn_name, hash, num_counters, index,
145
+ ) ;
146
+ bx. instrprof_increment ( fn_name, hash, num_counters, index) ;
132
147
}
133
148
CoverageKind :: Expression { id, lhs, op, rhs } => {
134
- bx. add_coverage_counter_expression ( instance, id, lhs, op, rhs, code_region) ;
149
+ debug ! (
150
+ "adding counter expression to coverage_map: instance={:?}, id={:?}, {:?} {:?} {:?}; region: {:?}" ,
151
+ instance, id, lhs, op, rhs, code_region,
152
+ ) ;
153
+ func_coverage. add_counter_expression ( id, lhs, op, rhs, code_region) ;
135
154
}
136
155
CoverageKind :: Unreachable => {
137
- bx. add_coverage_unreachable (
138
- instance,
139
- code_region. expect ( "unreachable regions always have code regions" ) ,
156
+ let code_region =
157
+ code_region. expect ( "unreachable regions always have code regions" ) ;
158
+ debug ! (
159
+ "adding unreachable code to coverage_map: instance={:?}, at {:?}" ,
160
+ instance, code_region,
140
161
) ;
162
+ func_coverage. add_unreachable_region ( code_region) ;
141
163
}
142
164
}
143
165
}
144
166
}
145
167
146
- // These methods used to be part of trait `CoverageInfoBuilderMethods`, but
147
- // after moving most coverage code out of SSA they are now just ordinary methods.
148
- impl < ' tcx > Builder < ' _ , ' _ , ' tcx > {
149
- /// Returns true if the function source hash was added to the coverage map (even if it had
150
- /// already been added, for this instance). Returns false *only* if `-C instrument-coverage` is
151
- /// not enabled (a coverage map is not being generated).
152
- fn set_function_source_hash (
153
- & mut self ,
154
- instance : Instance < ' tcx > ,
155
- function_source_hash : u64 ,
156
- ) -> bool {
157
- if let Some ( coverage_context) = self . coverage_context ( ) {
158
- debug ! (
159
- "ensuring function source hash is set for instance={:?}; function_source_hash={}" ,
160
- instance, function_source_hash,
161
- ) ;
162
- let mut coverage_map = coverage_context. function_coverage_map . borrow_mut ( ) ;
163
- coverage_map
164
- . entry ( instance)
165
- . or_insert_with ( || FunctionCoverage :: new ( self . tcx , instance) )
166
- . set_function_source_hash ( function_source_hash) ;
167
- true
168
- } else {
169
- false
170
- }
171
- }
172
-
173
- /// Returns true if the counter was added to the coverage map; false if `-C instrument-coverage`
174
- /// is not enabled (a coverage map is not being generated).
175
- fn add_coverage_counter (
176
- & mut self ,
177
- instance : Instance < ' tcx > ,
178
- id : CounterId ,
179
- region : CodeRegion ,
180
- ) -> bool {
181
- if let Some ( coverage_context) = self . coverage_context ( ) {
182
- debug ! (
183
- "adding counter to coverage_map: instance={:?}, id={:?}, region={:?}" ,
184
- instance, id, region,
185
- ) ;
186
- let mut coverage_map = coverage_context. function_coverage_map . borrow_mut ( ) ;
187
- coverage_map
188
- . entry ( instance)
189
- . or_insert_with ( || FunctionCoverage :: new ( self . tcx , instance) )
190
- . add_counter ( id, region) ;
191
- true
192
- } else {
193
- false
194
- }
195
- }
196
-
197
- /// Returns true if the expression was added to the coverage map; false if
198
- /// `-C instrument-coverage` is not enabled (a coverage map is not being generated).
199
- fn add_coverage_counter_expression (
200
- & mut self ,
201
- instance : Instance < ' tcx > ,
202
- id : ExpressionId ,
203
- lhs : Operand ,
204
- op : Op ,
205
- rhs : Operand ,
206
- region : Option < CodeRegion > ,
207
- ) -> bool {
208
- if let Some ( coverage_context) = self . coverage_context ( ) {
209
- debug ! (
210
- "adding counter expression to coverage_map: instance={:?}, id={:?}, {:?} {:?} {:?}; \
211
- region: {:?}",
212
- instance, id, lhs, op, rhs, region,
213
- ) ;
214
- let mut coverage_map = coverage_context. function_coverage_map . borrow_mut ( ) ;
215
- coverage_map
216
- . entry ( instance)
217
- . or_insert_with ( || FunctionCoverage :: new ( self . tcx , instance) )
218
- . add_counter_expression ( id, lhs, op, rhs, region) ;
219
- true
220
- } else {
221
- false
222
- }
223
- }
224
-
225
- /// Returns true if the region was added to the coverage map; false if `-C instrument-coverage`
226
- /// is not enabled (a coverage map is not being generated).
227
- fn add_coverage_unreachable ( & mut self , instance : Instance < ' tcx > , region : CodeRegion ) -> bool {
228
- if let Some ( coverage_context) = self . coverage_context ( ) {
229
- debug ! (
230
- "adding unreachable code to coverage_map: instance={:?}, at {:?}" ,
231
- instance, region,
232
- ) ;
233
- let mut coverage_map = coverage_context. function_coverage_map . borrow_mut ( ) ;
234
- coverage_map
235
- . entry ( instance)
236
- . or_insert_with ( || FunctionCoverage :: new ( self . tcx , instance) )
237
- . add_unreachable_region ( region) ;
238
- true
239
- } else {
240
- false
241
- }
242
- }
243
- }
244
-
245
168
fn declare_unused_fn < ' tcx > ( cx : & CodegenCx < ' _ , ' tcx > , def_id : DefId ) -> Instance < ' tcx > {
246
169
let tcx = cx. tcx ;
247
170
0 commit comments