Initialize LLVM time trace profiler on each code generation thread
In https://reviews.llvm.org/D71059 LLVM 11, the time trace profiler was extended to support multiple threads. `timeTraceProfilerInitialize` creates a thread local profiler instance. When a thread finishes `timeTraceProfilerFinishThread` moves a thread local instance into a global collection of instances. Finally when all codegen work is complete `timeTraceProfilerWrite` writes data from the current thread local instance and the instances in global collection of instances. Previously, the profiler was intialized on a single thread only. Since this thread performs no code generation on its own, the resulting profile was empty. Update LLVM codegen to initialize & finish time trace profiler on each code generation thread.
This commit is contained in:
parent
d22dd65835
commit
5a09e12135
6 changed files with 128 additions and 56 deletions
|
@ -76,6 +76,27 @@ mod value;
|
|||
#[derive(Clone)]
|
||||
pub struct LlvmCodegenBackend(());
|
||||
|
||||
struct TimeTraceProfiler {
|
||||
enabled: bool,
|
||||
}
|
||||
|
||||
impl TimeTraceProfiler {
|
||||
fn new(enabled: bool) -> Self {
|
||||
if enabled {
|
||||
unsafe { llvm::LLVMTimeTraceProfilerInitialize() }
|
||||
}
|
||||
TimeTraceProfiler { enabled }
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for TimeTraceProfiler {
|
||||
fn drop(&mut self) {
|
||||
if self.enabled {
|
||||
unsafe { llvm::LLVMTimeTraceProfilerFinishThread() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl ExtraBackendMethods for LlvmCodegenBackend {
|
||||
fn new_metadata(&self, tcx: TyCtxt<'_>, mod_name: &str) -> ModuleLlvm {
|
||||
ModuleLlvm::new_metadata(tcx, mod_name)
|
||||
|
@ -119,6 +140,34 @@ impl ExtraBackendMethods for LlvmCodegenBackend {
|
|||
fn tune_cpu<'b>(&self, sess: &'b Session) -> Option<&'b str> {
|
||||
llvm_util::tune_cpu(sess)
|
||||
}
|
||||
|
||||
fn spawn_thread<F, T>(time_trace: bool, f: F) -> std::thread::JoinHandle<T>
|
||||
where
|
||||
F: FnOnce() -> T,
|
||||
F: Send + 'static,
|
||||
T: Send + 'static,
|
||||
{
|
||||
std::thread::spawn(move || {
|
||||
let _profiler = TimeTraceProfiler::new(time_trace);
|
||||
f()
|
||||
})
|
||||
}
|
||||
|
||||
fn spawn_named_thread<F, T>(
|
||||
time_trace: bool,
|
||||
name: String,
|
||||
f: F,
|
||||
) -> std::io::Result<std::thread::JoinHandle<T>>
|
||||
where
|
||||
F: FnOnce() -> T,
|
||||
F: Send + 'static,
|
||||
T: Send + 'static,
|
||||
{
|
||||
std::thread::Builder::new().name(name).spawn(move || {
|
||||
let _profiler = TimeTraceProfiler::new(time_trace);
|
||||
f()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl WriteBackendMethods for LlvmCodegenBackend {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue