Skip to content
Snippets Groups Projects
  • David Faust's avatar
    b8977d92
    btf: add -gprune-btf option · b8977d92
    David Faust authored
    This patch adds a new option, -gprune-btf, to control BTF debug info
    generation.
    
    As the name implies, this option enables a kind of "pruning" of the BTF
    information before it is emitted.  When enabled, rather than emitting
    all type information translated from DWARF, only information for types
    directly used in the source program is emitted.
    
    The primary purpose of this pruning is to reduce the amount of
    unnecessary BTF information emitted, especially for BPF programs.  It is
    very common for BPF programs to include Linux kernel internal headers in
    order to have access to kernel data structures.  However, doing so often
    has the side effect of also adding type definitions for a large number
    of types which are not actually used by nor relevant to the program.
    In these cases, -gprune-btf commonly reduces the size of the resulting
    BTF information by 10x or more, as seen on average when compiling Linux
    kernel BPF selftests.  This both slims down the size of the resulting
    object and reduces the time required by the BPF loader to verify the
    program and its BTF information.
    
    Note that the pruning implemented in this patch follows the same rules
    as the BTF pruning performed unconditionally by LLVM's BPF backend when
    generating BTF.  In particular, the main sources of pruning are:
    
      1) Only generate BTF for types used by variables and functions at the
         file scope.
    
         Note that which variables are known to be "used" may differ
         slightly between LTO and non-LTO builds due to optimizations.  For
         non-LTO builds (and always for the BPF target), variables which are
         optimized away during compilation are considered to be unused, and
         they (along with their types) are pruned.  For LTO builds, such
         variables are not known to be optimized away by the time pruning
         occurs, so VAR records for them and information for their types may
         be present in the emitted BTF information.  This is a missed
         optimization that may be fixed in the future.
    
      2) Avoid emitting full BTF for struct and union types which are only
         pointed-to by members of other struct/union types.  In these cases,
         the full BTF_KIND_STRUCT or BTF_KIND_UNION which would normally
         be emitted is replaced with a BTF_KIND_FWD, as though the
         underlying type was a forward-declared struct or union type.
    
    gcc/
    	* btfout.cc (btf_used_types): New hash set.
    	(struct btf_fixup): New.
    	(fixups, forwards): New vecs.
    	(btf_output): Calculate num_types depending on debug_prune_btf.
    	(btf_early_finsih): New initialization for debug_prune_btf.
    	(btf_add_used_type): New function.
    	(btf_used_type_list_cb): Likewise.
    	(btf_collect_pruned_types): Likewise.
    	(btf_add_vars): Handle special case for variables in ".maps" section
    	when generating BTF for BPF CO-RE target.
    	(btf_late_finish): Use btf_collect_pruned_types when debug_prune_btf
    	is in effect.  Move some initialization to btf_early_finish.
    	(btf_finalize): Additional deallocation for debug_prune_btf.
    	* common.opt (gprune-btf): New flag.
    	* ctfc.cc (init_ctf_strtable): Make non-static.
    	* ctfc.h (init_ctf_strtable, ctfc_delete_strtab): Make extern.
    	* doc/invoke.texi (Debugging Options): Document -gprune-btf.
    
    gcc/testsuite/
    	* gcc.dg/debug/btf/btf-prune-1.c: New test.
    	* gcc.dg/debug/btf/btf-prune-2.c: Likewise.
    	* gcc.dg/debug/btf/btf-prune-3.c: Likewise.
    	* gcc.dg/debug/btf/btf-prune-maps.c: Likewise.
    b8977d92
    History
    btf: add -gprune-btf option
    David Faust authored
    This patch adds a new option, -gprune-btf, to control BTF debug info
    generation.
    
    As the name implies, this option enables a kind of "pruning" of the BTF
    information before it is emitted.  When enabled, rather than emitting
    all type information translated from DWARF, only information for types
    directly used in the source program is emitted.
    
    The primary purpose of this pruning is to reduce the amount of
    unnecessary BTF information emitted, especially for BPF programs.  It is
    very common for BPF programs to include Linux kernel internal headers in
    order to have access to kernel data structures.  However, doing so often
    has the side effect of also adding type definitions for a large number
    of types which are not actually used by nor relevant to the program.
    In these cases, -gprune-btf commonly reduces the size of the resulting
    BTF information by 10x or more, as seen on average when compiling Linux
    kernel BPF selftests.  This both slims down the size of the resulting
    object and reduces the time required by the BPF loader to verify the
    program and its BTF information.
    
    Note that the pruning implemented in this patch follows the same rules
    as the BTF pruning performed unconditionally by LLVM's BPF backend when
    generating BTF.  In particular, the main sources of pruning are:
    
      1) Only generate BTF for types used by variables and functions at the
         file scope.
    
         Note that which variables are known to be "used" may differ
         slightly between LTO and non-LTO builds due to optimizations.  For
         non-LTO builds (and always for the BPF target), variables which are
         optimized away during compilation are considered to be unused, and
         they (along with their types) are pruned.  For LTO builds, such
         variables are not known to be optimized away by the time pruning
         occurs, so VAR records for them and information for their types may
         be present in the emitted BTF information.  This is a missed
         optimization that may be fixed in the future.
    
      2) Avoid emitting full BTF for struct and union types which are only
         pointed-to by members of other struct/union types.  In these cases,
         the full BTF_KIND_STRUCT or BTF_KIND_UNION which would normally
         be emitted is replaced with a BTF_KIND_FWD, as though the
         underlying type was a forward-declared struct or union type.
    
    gcc/
    	* btfout.cc (btf_used_types): New hash set.
    	(struct btf_fixup): New.
    	(fixups, forwards): New vecs.
    	(btf_output): Calculate num_types depending on debug_prune_btf.
    	(btf_early_finsih): New initialization for debug_prune_btf.
    	(btf_add_used_type): New function.
    	(btf_used_type_list_cb): Likewise.
    	(btf_collect_pruned_types): Likewise.
    	(btf_add_vars): Handle special case for variables in ".maps" section
    	when generating BTF for BPF CO-RE target.
    	(btf_late_finish): Use btf_collect_pruned_types when debug_prune_btf
    	is in effect.  Move some initialization to btf_early_finish.
    	(btf_finalize): Additional deallocation for debug_prune_btf.
    	* common.opt (gprune-btf): New flag.
    	* ctfc.cc (init_ctf_strtable): Make non-static.
    	* ctfc.h (init_ctf_strtable, ctfc_delete_strtab): Make extern.
    	* doc/invoke.texi (Debugging Options): Document -gprune-btf.
    
    gcc/testsuite/
    	* gcc.dg/debug/btf/btf-prune-1.c: New test.
    	* gcc.dg/debug/btf/btf-prune-2.c: Likewise.
    	* gcc.dg/debug/btf/btf-prune-3.c: Likewise.
    	* gcc.dg/debug/btf/btf-prune-maps.c: Likewise.