From 598acffa609f1179d13f6d6004fec0b4bcf20b50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Fri, 14 Jul 2023 11:11:59 +0000 Subject: [PATCH 1/3] make opt diagnostic kinds printable --- compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs b/compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs index 45de284d22a..06e846a2b45 100644 --- a/compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs +++ b/compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs @@ -9,7 +9,7 @@ use super::{DiagnosticInfo, SMDiagnostic}; use rustc_span::InnerSpan; -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Debug)] pub enum OptimizationDiagnosticKind { OptimizationRemark, OptimizationMissed, From 77d01103a3b6d4cd0c1713d2f17233c620c7747d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Fri, 14 Jul 2023 14:26:15 +0000 Subject: [PATCH 2/3] filter LLVM diagnostics before crossing the rust bridge this will eliminate many short-lived allocations (e.g. 20% of the memory used building cargo) when unpacking the diagnostic and converting its various C++ strings into rust strings, just to be filtered out most of the time. --- compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp index ab5fa961b95..cbc18c0f6c6 100644 --- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp +++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp @@ -1905,12 +1905,19 @@ extern "C" void LLVMRustContextConfigureDiagnosticHandler( LlvmRemarkStreamer(std::move(LlvmRemarkStreamer)) {} virtual bool handleDiagnostics(const DiagnosticInfo &DI) override { - if (this->LlvmRemarkStreamer) { - if (auto *OptDiagBase = dyn_cast(&DI)) { - if (OptDiagBase->isEnabled()) { + // If this diagnostic is one of the optimization remark kinds, we can check if it's enabled + // before emitting it. This can avoid many short-lived allocations when unpacking the + // diagnostic and converting its various C++ strings into rust strings. + // FIXME: some diagnostic infos still allocate before we get here, and avoiding that would be + // good in the future. That will require changing a few call sites in LLVM. + if (auto *OptDiagBase = dyn_cast(&DI)) { + if (OptDiagBase->isEnabled()) { + if (this->LlvmRemarkStreamer) { this->LlvmRemarkStreamer->emit(*OptDiagBase); return true; } + } else { + return true; } } if (DiagnosticHandlerCallback) { From ca5a383fb6b16679b31029ab5da8438b5ef03e1e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9my=20Rakic?= Date: Fri, 14 Jul 2023 16:09:04 +0000 Subject: [PATCH 3/3] remove remark filtering on the rust side now that remarks are filtered before cg_llvm's diagnostic handler callback is called, we don't need to do the filtering post c++-to-rust conversion of the diagnostic. --- compiler/rustc_codegen_llvm/src/back/write.rs | 39 ++++++++----------- 1 file changed, 16 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs index 0f5e975445f..46874b50990 100644 --- a/compiler/rustc_codegen_llvm/src/back/write.rs +++ b/compiler/rustc_codegen_llvm/src/back/write.rs @@ -382,29 +382,22 @@ fn report_inline_asm( } llvm::diagnostic::Optimization(opt) => { - let enabled = match cgcx.remark { - Passes::All => true, - Passes::Some(ref v) => v.iter().any(|s| *s == opt.pass_name), - }; - - if enabled { - diag_handler.emit_note(FromLlvmOptimizationDiag { - filename: &opt.filename, - line: opt.line, - column: opt.column, - pass_name: &opt.pass_name, - kind: match opt.kind { - OptimizationDiagnosticKind::OptimizationRemark => "success", - OptimizationDiagnosticKind::OptimizationMissed - | OptimizationDiagnosticKind::OptimizationFailure => "missed", - OptimizationDiagnosticKind::OptimizationAnalysis - | OptimizationDiagnosticKind::OptimizationAnalysisFPCommute - | OptimizationDiagnosticKind::OptimizationAnalysisAliasing => "analysis", - OptimizationDiagnosticKind::OptimizationRemarkOther => "other", - }, - message: &opt.message, - }); - } + diag_handler.emit_note(FromLlvmOptimizationDiag { + filename: &opt.filename, + line: opt.line, + column: opt.column, + pass_name: &opt.pass_name, + kind: match opt.kind { + OptimizationDiagnosticKind::OptimizationRemark => "success", + OptimizationDiagnosticKind::OptimizationMissed + | OptimizationDiagnosticKind::OptimizationFailure => "missed", + OptimizationDiagnosticKind::OptimizationAnalysis + | OptimizationDiagnosticKind::OptimizationAnalysisFPCommute + | OptimizationDiagnosticKind::OptimizationAnalysisAliasing => "analysis", + OptimizationDiagnosticKind::OptimizationRemarkOther => "other", + }, + message: &opt.message, + }); } llvm::diagnostic::PGO(diagnostic_ref) | llvm::diagnostic::Linker(diagnostic_ref) => { let message = llvm::build_string(|s| {