Skip to content

Commit f5e46fe

Browse files
authored
Rollup merge of #73488 - richkadel:llvm-coverage-map-gen, r=tmandry
code coverage foundation for hash and num_counters This PR is the next iteration after PR #73011 (which is still waiting on bors to merge). @wesleywiser - PTAL r? @tmandry (FYI, I'm also working on injecting the coverage maps, in another branch, while waiting for these to merge.) Thanks!
2 parents 781b589 + 977ce57 commit f5e46fe

File tree

11 files changed

+240
-84
lines changed

11 files changed

+240
-84
lines changed

src/librustc_codegen_llvm/intrinsic.rs

+14-21
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ use rustc_middle::ty::layout::{FnAbiExt, HasTyCtxt};
2323
use rustc_middle::ty::{self, Ty};
2424
use rustc_middle::{bug, span_bug};
2525
use rustc_span::Span;
26-
use rustc_span::Symbol;
2726
use rustc_target::abi::{self, HasDataLayout, LayoutOf, Primitive};
2827
use rustc_target::spec::PanicStrategy;
2928

@@ -141,26 +140,20 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
141140
self.call(llfn, &[], None)
142141
}
143142
"count_code_region" => {
144-
if let ty::InstanceDef::Item(fn_def_id) = caller_instance.def {
145-
let caller_fn_path = tcx.def_path_str(fn_def_id);
146-
debug!(
147-
"count_code_region to llvm.instrprof.increment(fn_name={})",
148-
caller_fn_path
149-
);
150-
151-
// FIXME(richkadel): (1) Replace raw function name with mangled function name;
152-
// (2) Replace hardcoded `1234` in `hash` with a computed hash (as discussed in)
153-
// the MCP (compiler-team/issues/278); and replace the hardcoded `1` for
154-
// `num_counters` with the actual number of counters per function (when the
155-
// changes are made to inject more than one counter per function).
156-
let (fn_name, _len_val) = self.const_str(Symbol::intern(&caller_fn_path));
157-
let index = args[0].immediate();
158-
let hash = self.const_u64(1234);
159-
let num_counters = self.const_u32(1);
160-
self.instrprof_increment(fn_name, hash, num_counters, index)
161-
} else {
162-
bug!("intrinsic count_code_region: no src.instance");
163-
}
143+
// FIXME(richkadel): The current implementation assumes the MIR for the given
144+
// caller_instance represents a single function. Validate and/or correct if inlining
145+
// and/or monomorphization invalidates these assumptions.
146+
let coverage_data = tcx.coverage_data(caller_instance.def_id());
147+
let mangled_fn = tcx.symbol_name(caller_instance);
148+
let (mangled_fn_name, _len_val) = self.const_str(mangled_fn.name);
149+
let hash = self.const_u64(coverage_data.hash);
150+
let num_counters = self.const_u32(coverage_data.num_counters);
151+
let index = args[0].immediate();
152+
debug!(
153+
"count_code_region to LLVM intrinsic instrprof.increment(fn_name={}, hash={:?}, num_counters={:?}, index={:?})",
154+
mangled_fn.name, hash, num_counters, index
155+
);
156+
self.instrprof_increment(mangled_fn_name, hash, num_counters, index)
164157
}
165158
"va_start" => self.va_start(args[0].immediate()),
166159
"va_end" => self.va_end(args[0].immediate()),

src/librustc_metadata/locator.rs

+2
Original file line numberDiff line numberDiff line change
@@ -488,6 +488,8 @@ impl<'a> CrateLocator<'a> {
488488
&& self.triple != TargetTriple::from_triple(config::host_triple())
489489
{
490490
err.note(&format!("the `{}` target may not be installed", self.triple));
491+
} else if self.crate_name == sym::profiler_builtins {
492+
err.note(&"the compiler may have been built without the profiler runtime");
491493
}
492494
err.span_label(self.span, "can't find crate");
493495
err

src/librustc_middle/hir/map/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ fn fn_sig<'hir>(node: Node<'hir>) -> Option<&'hir FnSig<'hir>> {
5656
}
5757
}
5858

59-
fn associated_body<'hir>(node: Node<'hir>) -> Option<BodyId> {
59+
pub fn associated_body<'hir>(node: Node<'hir>) -> Option<BodyId> {
6060
match node {
6161
Node::Item(Item {
6262
kind: ItemKind::Const(_, body) | ItemKind::Static(.., body) | ItemKind::Fn(.., body),

src/librustc_middle/ich/hcx.rs

+31-2
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,15 @@ impl<'a> StableHashingContext<'a> {
6767
/// Don't use it for anything else or you'll run the risk of
6868
/// leaking data out of the tracking system.
6969
#[inline]
70-
pub fn new(
70+
fn new_with_or_without_spans(
7171
sess: &'a Session,
7272
krate: &'a hir::Crate<'a>,
7373
definitions: &'a Definitions,
7474
cstore: &'a dyn CrateStore,
75+
always_ignore_spans: bool,
7576
) -> Self {
76-
let hash_spans_initial = !sess.opts.debugging_opts.incremental_ignore_spans;
77+
let hash_spans_initial =
78+
!always_ignore_spans && !sess.opts.debugging_opts.incremental_ignore_spans;
7779

7880
StableHashingContext {
7981
sess,
@@ -88,6 +90,33 @@ impl<'a> StableHashingContext<'a> {
8890
}
8991
}
9092

93+
#[inline]
94+
pub fn new(
95+
sess: &'a Session,
96+
krate: &'a hir::Crate<'a>,
97+
definitions: &'a Definitions,
98+
cstore: &'a dyn CrateStore,
99+
) -> Self {
100+
Self::new_with_or_without_spans(
101+
sess,
102+
krate,
103+
definitions,
104+
cstore,
105+
/*always_ignore_spans=*/ false,
106+
)
107+
}
108+
109+
#[inline]
110+
pub fn ignore_spans(
111+
sess: &'a Session,
112+
krate: &'a hir::Crate<'a>,
113+
definitions: &'a Definitions,
114+
cstore: &'a dyn CrateStore,
115+
) -> Self {
116+
let always_ignore_spans = true;
117+
Self::new_with_or_without_spans(sess, krate, definitions, cstore, always_ignore_spans)
118+
}
119+
91120
#[inline]
92121
pub fn sess(&self) -> &'a Session {
93122
self.sess

src/librustc_middle/mir/mod.rs

+17-2
Original file line numberDiff line numberDiff line change
@@ -164,8 +164,8 @@ pub struct Body<'tcx> {
164164
/// The user may be writing e.g. `&[(SOME_CELL, 42)][i].1` and this would get promoted, because
165165
/// we'd statically know that no thing with interior mutability will ever be available to the
166166
/// user without some serious unsafe code. Now this means that our promoted is actually
167-
/// `&[(SOME_CELL, 42)]` and the MIR using it will do the `&promoted[i].1` projection because the
168-
/// index may be a runtime value. Such a promoted value is illegal because it has reachable
167+
/// `&[(SOME_CELL, 42)]` and the MIR using it will do the `&promoted[i].1` projection because
168+
/// the index may be a runtime value. Such a promoted value is illegal because it has reachable
169169
/// interior mutability. This flag just makes this situation very obvious where the previous
170170
/// implementation without the flag hid this situation silently.
171171
/// FIXME(oli-obk): rewrite the promoted during promotion to eliminate the cell components.
@@ -2921,3 +2921,18 @@ impl Location {
29212921
}
29222922
}
29232923
}
2924+
2925+
/// Coverage data associated with each function (MIR) instrumented with coverage counters, when
2926+
/// compiled with `-Zinstrument_coverage`. The query `tcx.coverage_data(DefId)` computes these
2927+
/// values on demand (during code generation). This query is only valid after executing the MIR pass
2928+
/// `InstrumentCoverage`.
2929+
#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)]
2930+
pub struct CoverageData {
2931+
/// A hash value that can be used by the consumer of the coverage profile data to detect
2932+
/// changes to the instrumented source of the associated MIR body (typically, for an
2933+
/// individual function).
2934+
pub hash: u64,
2935+
2936+
/// The total number of coverage region counters added to the MIR `Body`.
2937+
pub num_counters: u32,
2938+
}

src/librustc_middle/query/mod.rs

+6
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,12 @@ rustc_queries! {
231231
cache_on_disk_if { key.is_local() }
232232
}
233233

234+
query coverage_data(key: DefId) -> mir::CoverageData {
235+
desc { |tcx| "retrieving coverage data from MIR for `{}`", tcx.def_path_str(key) }
236+
storage(ArenaCacheSelector<'tcx>)
237+
cache_on_disk_if { key.is_local() }
238+
}
239+
234240
query promoted_mir(key: DefId) -> IndexVec<mir::Promoted, mir::Body<'tcx>> {
235241
desc { |tcx| "optimizing promoted MIR for `{}`", tcx.def_path_str(key) }
236242
storage(ArenaCacheSelector<'tcx>)

src/librustc_middle/ty/context.rs

+7
Original file line numberDiff line numberDiff line change
@@ -1307,6 +1307,13 @@ impl<'tcx> TyCtxt<'tcx> {
13071307
StableHashingContext::new(self.sess, krate, self.definitions, &*self.cstore)
13081308
}
13091309

1310+
#[inline(always)]
1311+
pub fn create_no_span_stable_hashing_context(self) -> StableHashingContext<'tcx> {
1312+
let krate = self.gcx.untracked_crate;
1313+
1314+
StableHashingContext::ignore_spans(self.sess, krate, self.definitions, &*self.cstore)
1315+
}
1316+
13101317
// This method makes sure that we have a DepNode and a Fingerprint for
13111318
// every upstream crate. It needs to be called once right after the tcx is
13121319
// created.

0 commit comments

Comments
 (0)