Skip to content

Commit 0de0a71

Browse files
committed
record llvm cgu instruction stats
1 parent 6ee97f1 commit 0de0a71

File tree

6 files changed

+52
-19
lines changed

6 files changed

+52
-19
lines changed

Cargo.lock

+4-2
Original file line numberDiff line numberDiff line change
@@ -3801,6 +3801,8 @@ dependencies = [
38013801
"rustc_span",
38023802
"rustc_symbol_mangling",
38033803
"rustc_target",
3804+
"serde",
3805+
"serde_json",
38043806
"smallvec",
38053807
"tempfile",
38063808
"tracing",
@@ -5186,9 +5188,9 @@ checksum = "5e9f0ab6ef7eb7353d9119c170a436d1bf248eea575ac42d19d12f4e34130831"
51865188

51875189
[[package]]
51885190
name = "snapbox"
5189-
version = "0.4.1"
5191+
version = "0.4.7"
51905192
source = "registry+https://github.com/rust-lang/crates.io-index"
5191-
checksum = "827c00e91b15e2674d8a5270bae91f898693cbf9561cbb58d8eaa31974597293"
5193+
checksum = "09c20d8ee8713199cfd44148b70e47cb94f3e8dc538d727d31788f49e67b623e"
51925194
dependencies = [
51935195
"concolor",
51945196
"content_inspector",

compiler/rustc_codegen_llvm/Cargo.toml

+2
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,5 @@ smallvec = { version = "1.8.1", features = ["union", "may_dangle"] }
3636
rustc_ast = { path = "../rustc_ast" }
3737
rustc_span = { path = "../rustc_span" }
3838
tempfile = "3.2.0"
39+
serde = { version = "1", features = [ "derive" ]}
40+
serde_json = "1"

compiler/rustc_codegen_llvm/src/back/write.rs

+23-4
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ use rustc_codegen_ssa::back::write::{
2020
};
2121
use rustc_codegen_ssa::traits::*;
2222
use rustc_codegen_ssa::{CompiledModule, ModuleCodegen};
23+
use rustc_data_structures::fx::FxHashMap;
2324
use rustc_data_structures::profiling::SelfProfilerRef;
2425
use rustc_data_structures::small_c_str::SmallCStr;
2526
use rustc_errors::{FatalError, Handler, Level};
@@ -568,10 +569,8 @@ pub(crate) unsafe fn codegen(
568569
let llcx = &*module.module_llvm.llcx;
569570
let tm = &*module.module_llvm.tm;
570571
let module_name = module.name.clone();
571-
let count = unsafe { llvm::LLVMRustModuleInstructionStats(&llmod) };
572-
println!("llvm-module: {module_name} = {count}");
573572
let module_name = Some(&module_name[..]);
574-
let handlers = DiagnosticHandlers::new(cgcx, diag_handler, llcx);
573+
let _handlers = DiagnosticHandlers::new(cgcx, diag_handler, llcx);
575574

576575
if cgcx.msvc_imps_needed {
577576
create_msvc_imps(cgcx, llcx, llmod);
@@ -763,7 +762,7 @@ pub(crate) unsafe fn codegen(
763762
EmitObj::None => {}
764763
}
765764

766-
drop(handlers);
765+
record_llvm_cgu_instructions_stats(&cgcx.prof, llmod);
767766
}
768767

769768
// `.dwo` files are only emitted if:
@@ -976,3 +975,23 @@ fn record_artifact_size(
976975
self_profiler_ref.artifact_size(artifact_kind, artifact_name.to_string_lossy(), file_size);
977976
}
978977
}
978+
979+
fn record_llvm_cgu_instructions_stats(prof: &SelfProfilerRef, llmod: &llvm::Module) {
980+
if !prof.enabled() {
981+
return;
982+
}
983+
984+
let raw_stats =
985+
llvm::build_string(|s| unsafe { llvm::LLVMRustModuleInstructionStats(&llmod, s) })
986+
.expect("cannot get module instruction stats");
987+
#[derive(serde::Deserialize)]
988+
struct InstructionsStats {
989+
module: String,
990+
_functions: FxHashMap<String, u64>,
991+
total: u64,
992+
}
993+
994+
let InstructionsStats { module, total, .. } =
995+
serde_json::from_str(&raw_stats).expect("cannot parse llvm cgu instructions stats");
996+
prof.artifact_size("cgu_instructions", module, total);
997+
}

compiler/rustc_codegen_llvm/src/llvm/ffi.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -2410,7 +2410,8 @@ extern "C" {
24102410
pub fn LLVMRustModuleBufferLen(p: &ModuleBuffer) -> usize;
24112411
pub fn LLVMRustModuleBufferFree(p: &'static mut ModuleBuffer);
24122412
pub fn LLVMRustModuleCost(M: &Module) -> u64;
2413-
pub fn LLVMRustModuleInstructionStats(M: &Module) -> u64;
2413+
#[allow(improper_ctypes)]
2414+
pub fn LLVMRustModuleInstructionStats(M: &Module, Str: &RustString);
24142415

24152416
pub fn LLVMRustThinLTOBufferCreate(M: &Module, is_thin: bool) -> &'static mut ThinLTOBuffer;
24162417
pub fn LLVMRustThinLTOBufferFree(M: &'static mut ThinLTOBuffer);

compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "llvm/Support/Debug.h"
1515
#include "llvm/Support/DynamicLibrary.h"
1616
#include "llvm/Support/FormattedStream.h"
17+
#include "llvm/Support/JSON.h"
1718
#include "llvm/Support/Host.h"
1819
#include "llvm/Support/Memory.h"
1920
#include "llvm/Support/SourceMgr.h"

compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp

+20-12
Original file line numberDiff line numberDiff line change
@@ -1751,18 +1751,26 @@ LLVMRustModuleCost(LLVMModuleRef M) {
17511751
return std::distance(std::begin(f), std::end(f));
17521752
}
17531753

1754-
extern "C" uint64_t
1755-
LLVMRustModuleInstructionStats(LLVMModuleRef M) {
1756-
auto f = unwrap(M)->functions();
1757-
raw_fd_ostream OS(2, false); // stderr.
1758-
for (auto &func : f)
1759-
{
1760-
auto name = func.getName();
1761-
1762-
auto count = func.getInstructionCount();
1763-
OS << name << "\t" << count << "\n";
1764-
}
1765-
return unwrap(M)->getInstructionCount();
1754+
extern "C" void
1755+
LLVMRustModuleInstructionStats(LLVMModuleRef M, RustStringRef Str)
1756+
{
1757+
RawRustStringOstream OS(Str);
1758+
llvm::json::OStream JOS(OS);
1759+
auto Module = unwrap(M);
1760+
1761+
JOS.object([&]
1762+
{
1763+
JOS.attribute("module", Module->getName());
1764+
JOS.attribute("total", Module->getInstructionCount());
1765+
JOS.attributeArray("functions", [&] {
1766+
auto functions = Module->functions();
1767+
for (auto &f: functions) {
1768+
JOS.object([&] {
1769+
JOS.attribute(f.getName(),f.getInstructionCount());
1770+
});
1771+
}
1772+
1773+
}); });
17661774
}
17671775

17681776
// Vector reductions:

0 commit comments

Comments
 (0)