@@ -17,10 +17,11 @@ use rustc_hir::def_id::DefId;
17
17
use rustc_llvm:: RustString ;
18
18
use rustc_middle:: bug;
19
19
use rustc_middle:: mir:: coverage:: {
20
- CodeRegion , CounterValueReference , ExpressionOperandId , InjectedExpressionId , Op ,
20
+ CodeRegion , CounterValueReference , CoverageKind , ExpressionOperandId , InjectedExpressionId , Op ,
21
21
} ;
22
+ use rustc_middle:: mir:: Coverage ;
22
23
use rustc_middle:: ty;
23
- use rustc_middle:: ty:: layout:: FnAbiOf ;
24
+ use rustc_middle:: ty:: layout:: { FnAbiOf , HasTyCtxt } ;
24
25
use rustc_middle:: ty:: subst:: InternalSubsts ;
25
26
use rustc_middle:: ty:: Instance ;
26
27
@@ -94,6 +95,54 @@ impl<'ll, 'tcx> CoverageInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
94
95
}
95
96
96
97
impl < ' tcx > CoverageInfoBuilderMethods < ' tcx > for Builder < ' _ , ' _ , ' tcx > {
98
+ fn add_coverage ( & mut self , instance : Instance < ' tcx > , coverage : & Coverage ) {
99
+ let bx = self ;
100
+
101
+ let Coverage { kind, code_region } = coverage. clone ( ) ;
102
+ match kind {
103
+ CoverageKind :: Counter { function_source_hash, id } => {
104
+ if bx. set_function_source_hash ( instance, function_source_hash) {
105
+ // If `set_function_source_hash()` returned true, the coverage map is enabled,
106
+ // so continue adding the counter.
107
+ if let Some ( code_region) = code_region {
108
+ // Note: Some counters do not have code regions, but may still be referenced
109
+ // from expressions. In that case, don't add the counter to the coverage map,
110
+ // but do inject the counter intrinsic.
111
+ bx. add_coverage_counter ( instance, id, code_region) ;
112
+ }
113
+
114
+ let coverageinfo = bx. tcx ( ) . coverageinfo ( instance. def ) ;
115
+
116
+ let fn_name = bx. get_pgo_func_name_var ( instance) ;
117
+ let hash = bx. const_u64 ( function_source_hash) ;
118
+ let num_counters = bx. const_u32 ( coverageinfo. num_counters ) ;
119
+ let index = bx. const_u32 ( id. zero_based_index ( ) ) ;
120
+ debug ! (
121
+ "codegen intrinsic instrprof.increment(fn_name={:?}, hash={:?}, num_counters={:?}, index={:?})" ,
122
+ fn_name, hash, num_counters, index,
123
+ ) ;
124
+ bx. instrprof_increment ( fn_name, hash, num_counters, index) ;
125
+ }
126
+ }
127
+ CoverageKind :: Expression { id, lhs, op, rhs } => {
128
+ bx. add_coverage_counter_expression ( instance, id, lhs, op, rhs, code_region) ;
129
+ }
130
+ CoverageKind :: Unreachable => {
131
+ bx. add_coverage_unreachable (
132
+ instance,
133
+ code_region. expect ( "unreachable regions always have code regions" ) ,
134
+ ) ;
135
+ }
136
+ }
137
+ }
138
+ }
139
+
140
+ // These methods used to be part of trait `CoverageInfoBuilderMethods`, but
141
+ // after moving most coverage code out of SSA they are now just ordinary methods.
142
+ impl < ' tcx > Builder < ' _ , ' _ , ' tcx > {
143
+ /// Returns true if the function source hash was added to the coverage map (even if it had
144
+ /// already been added, for this instance). Returns false *only* if `-C instrument-coverage` is
145
+ /// not enabled (a coverage map is not being generated).
97
146
fn set_function_source_hash (
98
147
& mut self ,
99
148
instance : Instance < ' tcx > ,
@@ -115,6 +164,8 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
115
164
}
116
165
}
117
166
167
+ /// Returns true if the counter was added to the coverage map; false if `-C instrument-coverage`
168
+ /// is not enabled (a coverage map is not being generated).
118
169
fn add_coverage_counter (
119
170
& mut self ,
120
171
instance : Instance < ' tcx > ,
@@ -137,6 +188,8 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
137
188
}
138
189
}
139
190
191
+ /// Returns true if the expression was added to the coverage map; false if
192
+ /// `-C instrument-coverage` is not enabled (a coverage map is not being generated).
140
193
fn add_coverage_counter_expression (
141
194
& mut self ,
142
195
instance : Instance < ' tcx > ,
@@ -163,6 +216,8 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
163
216
}
164
217
}
165
218
219
+ /// Returns true if the region was added to the coverage map; false if `-C instrument-coverage`
220
+ /// is not enabled (a coverage map is not being generated).
166
221
fn add_coverage_unreachable ( & mut self , instance : Instance < ' tcx > , region : CodeRegion ) -> bool {
167
222
if let Some ( coverage_context) = self . coverage_context ( ) {
168
223
debug ! (
0 commit comments