1
Fork 0

debuginfo: add compiler option to allow compressed debuginfo sections

LLVM already supports emitting compressed debuginfo. In debuginfo=full
builds, the debug section is often a large amount of data, and it
typically compresses very well (3x is not unreasonable.) We add a new
knob to allow debuginfo to be compressed when the matching LLVM
functionality is present. Like clang, if a known-but-disabled
compression mechanism is requested, we disable compression and emit
uncompressed debuginfo sections.

The API is different enough on older LLVMs we just pretend the support
is missing on LLVM older than 16.
This commit is contained in:
Augie Fackler 2023-07-12 17:07:34 -04:00
parent 9ad0396a34
commit af9e55068c
10 changed files with 135 additions and 7 deletions

View file

@ -381,6 +381,24 @@ pub enum DebugInfo {
Full,
}
#[derive(Clone, Copy, Debug, PartialEq, Hash)]
pub enum DebugInfoCompression {
None,
Zlib,
Zstd,
}
impl ToString for DebugInfoCompression {
fn to_string(&self) -> String {
match self {
DebugInfoCompression::None => "none",
DebugInfoCompression::Zlib => "zlib",
DebugInfoCompression::Zstd => "zstd",
}
.to_owned()
}
}
/// Split debug-information is enabled by `-C split-debuginfo`, this enum is only used if split
/// debug-information is enabled (in either `Packed` or `Unpacked` modes), and the platform
/// uses DWARF for debug-information.
@ -1015,6 +1033,7 @@ impl Default for Options {
crate_types: Vec::new(),
optimize: OptLevel::No,
debuginfo: DebugInfo::None,
debuginfo_compression: DebugInfoCompression::None,
lint_opts: Vec::new(),
lint_cap: None,
describe_lints: false,
@ -2277,6 +2296,13 @@ fn select_debuginfo(matches: &getopts::Matches, cg: &CodegenOptions) -> DebugInf
if max_g > max_c { DebugInfo::Full } else { cg.debuginfo }
}
fn select_debuginfo_compression(
_handler: &EarlyErrorHandler,
unstable_opts: &UnstableOptions,
) -> DebugInfoCompression {
unstable_opts.debuginfo_compression
}
pub(crate) fn parse_assert_incr_state(
handler: &EarlyErrorHandler,
opt_assertion: &Option<String>,
@ -2752,6 +2778,8 @@ pub fn build_session_options(
// for more details.
let debug_assertions = cg.debug_assertions.unwrap_or(opt_level == OptLevel::No);
let debuginfo = select_debuginfo(matches, &cg);
let debuginfo_compression: DebugInfoCompression =
select_debuginfo_compression(handler, &unstable_opts);
let mut search_paths = vec![];
for s in &matches.opt_strs("L") {
@ -2828,6 +2856,7 @@ pub fn build_session_options(
crate_types,
optimize: opt_level,
debuginfo,
debuginfo_compression,
lint_opts,
lint_cap,
describe_lints,
@ -3113,11 +3142,11 @@ impl PpMode {
/// how the hash should be calculated when adding a new command-line argument.
pub(crate) mod dep_tracking {
use super::{
BranchProtection, CFGuard, CFProtection, CrateType, DebugInfo, ErrorOutputType,
InstrumentCoverage, InstrumentXRay, LdImpl, LinkerPluginLto, LocationDetail, LtoCli,
OomStrategy, OptLevel, OutFileName, OutputType, OutputTypes, Passes, ResolveDocLinks,
SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath, SymbolManglingVersion,
TraitSolver, TrimmedDefPaths,
BranchProtection, CFGuard, CFProtection, CrateType, DebugInfo, DebugInfoCompression,
ErrorOutputType, InstrumentCoverage, InstrumentXRay, LdImpl, LinkerPluginLto,
LocationDetail, LtoCli, OomStrategy, OptLevel, OutFileName, OutputType, OutputTypes,
Passes, ResolveDocLinks, SourceFileHashAlgorithm, SplitDwarfKind, SwitchWithOptPath,
SymbolManglingVersion, TraitSolver, TrimmedDefPaths,
};
use crate::lint;
use crate::options::WasiExecModel;
@ -3195,6 +3224,7 @@ pub(crate) mod dep_tracking {
OptLevel,
LtoCli,
DebugInfo,
DebugInfoCompression,
UnstableFeatures,
NativeLib,
NativeLibKind,

View file

@ -139,6 +139,7 @@ top_level_options!(
/// can influence whether overflow checks are done or not.
debug_assertions: bool [TRACKED],
debuginfo: DebugInfo [TRACKED],
debuginfo_compression: DebugInfoCompression [TRACKED],
lint_opts: Vec<(String, lint::Level)> [TRACKED_NO_CRATE_HASH],
lint_cap: Option<lint::Level> [TRACKED_NO_CRATE_HASH],
describe_lints: bool [UNTRACKED],
@ -376,6 +377,7 @@ mod desc {
"either a boolean (`yes`, `no`, `on`, `off`, etc), `checks`, or `nochecks`";
pub const parse_cfprotection: &str = "`none`|`no`|`n` (default), `branch`, `return`, or `full`|`yes`|`y` (equivalent to `branch` and `return`)";
pub const parse_debuginfo: &str = "either an integer (0, 1, 2), `none`, `line-directives-only`, `line-tables-only`, `limited`, or `full`";
pub const parse_debuginfo_compression: &str = "one of `none`, `zlib`, or `zstd`";
pub const parse_strip: &str = "either `none`, `debuginfo`, or `symbols`";
pub const parse_linker_flavor: &str = ::rustc_target::spec::LinkerFlavorCli::one_of();
pub const parse_optimization_fuel: &str = "crate=integer";
@ -782,6 +784,19 @@ mod parse {
true
}
pub(crate) fn parse_debuginfo_compression(
slot: &mut DebugInfoCompression,
v: Option<&str>,
) -> bool {
match v {
Some("none") => *slot = DebugInfoCompression::None,
Some("zlib") => *slot = DebugInfoCompression::Zlib,
Some("zstd") => *slot = DebugInfoCompression::Zstd,
_ => return false,
};
true
}
pub(crate) fn parse_linker_flavor(slot: &mut Option<LinkerFlavorCli>, v: Option<&str>) -> bool {
match v.and_then(LinkerFlavorCli::from_str) {
Some(lf) => *slot = Some(lf),
@ -1422,7 +1437,9 @@ options! {
"inject the given attribute in the crate"),
debug_info_for_profiling: bool = (false, parse_bool, [TRACKED],
"emit discriminators and other data necessary for AutoFDO"),
debug_macros: bool = (false, parse_bool, [TRACKED],
debuginfo_compression: DebugInfoCompression = (DebugInfoCompression::None, parse_debuginfo_compression, [TRACKED],
"compress debug info sections (none, zlib, zstd, default: none)"),
debug_macros: bool = (false, parse_bool, [TRACKED],
"emit line numbers debug info inside macros (default: no)"),
deduplicate_diagnostics: bool = (true, parse_bool, [UNTRACKED],
"deduplicate identical diagnostics (default: yes)"),