rustc_llvm: Add a -Z print-llvm-stats
option to expose LLVM statistics.
LLVM has a neat [statistics] feature that tracks how often optimizations kick in. It's very handy for optimization work. Since we expose the LLVM pass timings, I thought it made sense to expose the LLVM statistics too. [statistics]: https://llvm.org/docs/ProgrammersManual.html#the-statistic-class-stats-option
This commit is contained in:
parent
55be59d2ce
commit
2d47816cba
10 changed files with 35 additions and 0 deletions
|
@ -239,6 +239,10 @@ impl WriteBackendMethods for GccCodegenBackend {
|
||||||
unimplemented!();
|
unimplemented!();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn print_statistics(&self) {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
|
||||||
unsafe fn optimize(_cgcx: &CodegenContext<Self>, _diag_handler: &Handler, module: &ModuleCodegen<Self::Module>, config: &ModuleConfig) -> Result<(), FatalError> {
|
unsafe fn optimize(_cgcx: &CodegenContext<Self>, _diag_handler: &Handler, module: &ModuleCodegen<Self::Module>, config: &ModuleConfig) -> Result<(), FatalError> {
|
||||||
module.module_llvm.context.set_optimization_level(to_gcc_opt_level(config.opt_level));
|
module.module_llvm.context.set_optimization_level(to_gcc_opt_level(config.opt_level));
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -181,6 +181,11 @@ impl WriteBackendMethods for LlvmCodegenBackend {
|
||||||
llvm::LLVMRustPrintPassTimings();
|
llvm::LLVMRustPrintPassTimings();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
fn print_statistics(&self) {
|
||||||
|
unsafe {
|
||||||
|
llvm::LLVMRustPrintStatistics();
|
||||||
|
}
|
||||||
|
}
|
||||||
fn run_link(
|
fn run_link(
|
||||||
cgcx: &CodegenContext<Self>,
|
cgcx: &CodegenContext<Self>,
|
||||||
diag_handler: &Handler,
|
diag_handler: &Handler,
|
||||||
|
|
|
@ -1870,6 +1870,9 @@ extern "C" {
|
||||||
/// Print the pass timings since static dtors aren't picking them up.
|
/// Print the pass timings since static dtors aren't picking them up.
|
||||||
pub fn LLVMRustPrintPassTimings();
|
pub fn LLVMRustPrintPassTimings();
|
||||||
|
|
||||||
|
/// Print the statistics since static dtors aren't picking them up.
|
||||||
|
pub fn LLVMRustPrintStatistics();
|
||||||
|
|
||||||
pub fn LLVMStructCreateNamed(C: &Context, Name: *const c_char) -> &Type;
|
pub fn LLVMStructCreateNamed(C: &Context, Name: *const c_char) -> &Type;
|
||||||
|
|
||||||
pub fn LLVMStructSetBody<'a>(
|
pub fn LLVMStructSetBody<'a>(
|
||||||
|
|
|
@ -110,6 +110,10 @@ unsafe fn configure_llvm(sess: &Session) {
|
||||||
// Use non-zero `import-instr-limit` multiplier for cold callsites.
|
// Use non-zero `import-instr-limit` multiplier for cold callsites.
|
||||||
add("-import-cold-multiplier=0.1", false);
|
add("-import-cold-multiplier=0.1", false);
|
||||||
|
|
||||||
|
if sess.print_llvm_stats() {
|
||||||
|
add("-stats", false);
|
||||||
|
}
|
||||||
|
|
||||||
for arg in sess_args {
|
for arg in sess_args {
|
||||||
add(&(*arg), true);
|
add(&(*arg), true);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1945,6 +1945,10 @@ impl<B: ExtraBackendMethods> OngoingCodegen<B> {
|
||||||
self.backend.print_pass_timings()
|
self.backend.print_pass_timings()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if sess.print_llvm_stats() {
|
||||||
|
self.backend.print_statistics()
|
||||||
|
}
|
||||||
|
|
||||||
(
|
(
|
||||||
CodegenResults {
|
CodegenResults {
|
||||||
metadata: self.metadata,
|
metadata: self.metadata,
|
||||||
|
|
|
@ -35,6 +35,7 @@ pub trait WriteBackendMethods: 'static + Sized + Clone {
|
||||||
cached_modules: Vec<(SerializedModule<Self::ModuleBuffer>, WorkProduct)>,
|
cached_modules: Vec<(SerializedModule<Self::ModuleBuffer>, WorkProduct)>,
|
||||||
) -> Result<(Vec<LtoModuleCodegen<Self>>, Vec<WorkProduct>), FatalError>;
|
) -> Result<(Vec<LtoModuleCodegen<Self>>, Vec<WorkProduct>), FatalError>;
|
||||||
fn print_pass_timings(&self);
|
fn print_pass_timings(&self);
|
||||||
|
fn print_statistics(&self);
|
||||||
unsafe fn optimize(
|
unsafe fn optimize(
|
||||||
cgcx: &CodegenContext<Self>,
|
cgcx: &CodegenContext<Self>,
|
||||||
diag_handler: &Handler,
|
diag_handler: &Handler,
|
||||||
|
|
|
@ -715,6 +715,7 @@ fn test_unstable_options_tracking_hash() {
|
||||||
// `pre_link_arg` is omitted because it just forwards to `pre_link_args`.
|
// `pre_link_arg` is omitted because it just forwards to `pre_link_args`.
|
||||||
untracked!(pre_link_args, vec![String::from("abc"), String::from("def")]);
|
untracked!(pre_link_args, vec![String::from("abc"), String::from("def")]);
|
||||||
untracked!(print_llvm_passes, true);
|
untracked!(print_llvm_passes, true);
|
||||||
|
untracked!(print_llvm_stats, true);
|
||||||
untracked!(print_mono_items, Some(String::from("abc")));
|
untracked!(print_mono_items, Some(String::from("abc")));
|
||||||
untracked!(print_type_sizes, true);
|
untracked!(print_type_sizes, true);
|
||||||
untracked!(proc_macro_backtrace, true);
|
untracked!(proc_macro_backtrace, true);
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#include "LLVMWrapper.h"
|
#include "LLVMWrapper.h"
|
||||||
|
#include "llvm/ADT/Statistic.h"
|
||||||
#include "llvm/IR/DebugInfoMetadata.h"
|
#include "llvm/IR/DebugInfoMetadata.h"
|
||||||
#include "llvm/IR/DiagnosticHandler.h"
|
#include "llvm/IR/DiagnosticHandler.h"
|
||||||
#include "llvm/IR/DiagnosticInfo.h"
|
#include "llvm/IR/DiagnosticInfo.h"
|
||||||
|
@ -116,6 +117,11 @@ extern "C" void LLVMRustPrintPassTimings() {
|
||||||
TimerGroup::printAll(OS);
|
TimerGroup::printAll(OS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern "C" void LLVMRustPrintStatistics() {
|
||||||
|
raw_fd_ostream OS(2, false); // stderr.
|
||||||
|
llvm::PrintStatistics(OS);
|
||||||
|
}
|
||||||
|
|
||||||
extern "C" LLVMValueRef LLVMRustGetNamedValue(LLVMModuleRef M, const char *Name,
|
extern "C" LLVMValueRef LLVMRustGetNamedValue(LLVMModuleRef M, const char *Name,
|
||||||
size_t NameLen) {
|
size_t NameLen) {
|
||||||
return wrap(unwrap(M)->getNamedValue(StringRef(Name, NameLen)));
|
return wrap(unwrap(M)->getNamedValue(StringRef(Name, NameLen)));
|
||||||
|
|
|
@ -1672,6 +1672,9 @@ options! {
|
||||||
"make rustc print the total optimization fuel used by a crate"),
|
"make rustc print the total optimization fuel used by a crate"),
|
||||||
print_llvm_passes: bool = (false, parse_bool, [UNTRACKED],
|
print_llvm_passes: bool = (false, parse_bool, [UNTRACKED],
|
||||||
"print the LLVM optimization passes being run (default: no)"),
|
"print the LLVM optimization passes being run (default: no)"),
|
||||||
|
#[rustc_lint_opt_deny_field_access("use `Session::print_llvm_stats` instead of this field")]
|
||||||
|
print_llvm_stats: bool = (true, parse_bool, [UNTRACKED],
|
||||||
|
"print LLVM statistics (default: no)"),
|
||||||
print_mono_items: Option<String> = (None, parse_opt_string, [UNTRACKED],
|
print_mono_items: Option<String> = (None, parse_opt_string, [UNTRACKED],
|
||||||
"print the result of the monomorphization collection pass"),
|
"print the result of the monomorphization collection pass"),
|
||||||
print_type_sizes: bool = (false, parse_bool, [UNTRACKED],
|
print_type_sizes: bool = (false, parse_bool, [UNTRACKED],
|
||||||
|
|
|
@ -1057,6 +1057,10 @@ impl Session {
|
||||||
self.opts.unstable_opts.verbose
|
self.opts.unstable_opts.verbose
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn print_llvm_stats(&self) -> bool {
|
||||||
|
self.opts.unstable_opts.print_llvm_stats
|
||||||
|
}
|
||||||
|
|
||||||
pub fn verify_llvm_ir(&self) -> bool {
|
pub fn verify_llvm_ir(&self) -> bool {
|
||||||
self.opts.unstable_opts.verify_llvm_ir || option_env!("RUSTC_VERIFY_LLVM_IR").is_some()
|
self.opts.unstable_opts.verify_llvm_ir || option_env!("RUSTC_VERIFY_LLVM_IR").is_some()
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue