]> git.lizzy.rs Git - rust.git/blob - compiler/rustc_codegen_llvm/src/back/profiling.rs
Auto merge of #107843 - bjorn3:sync_cg_clif-2023-02-09, r=bjorn3
[rust.git] / compiler / rustc_codegen_llvm / src / back / profiling.rs
1 use measureme::{event_id::SEPARATOR_BYTE, EventId, StringComponent, StringId};
2 use rustc_data_structures::profiling::{SelfProfiler, TimingGuard};
3 use std::ffi::{c_void, CStr};
4 use std::os::raw::c_char;
5 use std::sync::Arc;
6
7 fn llvm_args_to_string_id(profiler: &SelfProfiler, pass_name: &str, ir_name: &str) -> EventId {
8     let pass_name = profiler.get_or_alloc_cached_string(pass_name);
9     let mut components = vec![StringComponent::Ref(pass_name)];
10     // handle that LazyCallGraph::SCC is a comma separated list within parentheses
11     let parentheses: &[_] = &['(', ')'];
12     let trimmed = ir_name.trim_matches(parentheses);
13     for part in trimmed.split(", ") {
14         let demangled_ir_name = rustc_demangle::demangle(part).to_string();
15         let ir_name = profiler.get_or_alloc_cached_string(demangled_ir_name);
16         components.push(StringComponent::Value(SEPARATOR_BYTE));
17         components.push(StringComponent::Ref(ir_name));
18     }
19     EventId::from_label(profiler.alloc_string(components.as_slice()))
20 }
21
22 pub struct LlvmSelfProfiler<'a> {
23     profiler: Arc<SelfProfiler>,
24     stack: Vec<TimingGuard<'a>>,
25     llvm_pass_event_kind: StringId,
26 }
27
28 impl<'a> LlvmSelfProfiler<'a> {
29     pub fn new(profiler: Arc<SelfProfiler>) -> Self {
30         let llvm_pass_event_kind = profiler.alloc_string("LLVM Pass");
31         Self { profiler, stack: Vec::default(), llvm_pass_event_kind }
32     }
33
34     fn before_pass_callback(&'a mut self, pass_name: &str, ir_name: &str) {
35         let event_id = llvm_args_to_string_id(&self.profiler, pass_name, ir_name);
36
37         self.stack.push(TimingGuard::start(&self.profiler, self.llvm_pass_event_kind, event_id));
38     }
39     fn after_pass_callback(&mut self) {
40         self.stack.pop();
41     }
42 }
43
44 pub unsafe extern "C" fn selfprofile_before_pass_callback(
45     llvm_self_profiler: *mut c_void,
46     pass_name: *const c_char,
47     ir_name: *const c_char,
48 ) {
49     let llvm_self_profiler = &mut *(llvm_self_profiler as *mut LlvmSelfProfiler<'_>);
50     let pass_name = CStr::from_ptr(pass_name).to_str().expect("valid UTF-8");
51     let ir_name = CStr::from_ptr(ir_name).to_str().expect("valid UTF-8");
52     llvm_self_profiler.before_pass_callback(pass_name, ir_name);
53 }
54
55 pub unsafe extern "C" fn selfprofile_after_pass_callback(llvm_self_profiler: *mut c_void) {
56     let llvm_self_profiler = &mut *(llvm_self_profiler as *mut LlvmSelfProfiler<'_>);
57     llvm_self_profiler.after_pass_callback();
58 }