[gcc r15-1787] ctf, btf: restructure CTF/BTF emission

2024-07-02 Thread David Faust via Gcc-cvs
https://gcc.gnu.org/g:d3f586ec50d3d502e0727e8307ae76770fdaee79

commit r15-1787-gd3f586ec50d3d502e0727e8307ae76770fdaee79
Author: David Faust 
Date:   Thu May 30 14:06:27 2024 -0700

ctf, btf: restructure CTF/BTF emission

This commit makes some structural changes to the CTF/BTF debug info
emission.  In particular:

 a) CTF is new always fully generated and emitted before any
BTF-related procedures are run.  This means that BTF-related
functions can change, even irreversibly, the shared in-memory
representation used by the two formats without issue.

 b) BTF generation has fewer entry points, and is cleanly divided
into early_finish and finish.

 c) BTF is now always emitted at finish (called from dwarf2out_finish),
for all targets in non-LTO builds, rather than being emitted at
early_finish for targets other than BPF CO-RE.  In LTO builds,
BTF is emitted at early_finish as before.

Note that this change alone does not alter the contents of BTF at
all, regardless of whether it would have previously been emitted at
early_finish or finish, because the calculation of the BTF to be
emitted is not moved by this patch, only the write-out.

The changes are transparent to both CTF and BTF emission.

gcc/
* btfout.cc (btf_init_postprocess): Rename to...
(btf_early_finish): ...this.
(btf_output): Rename to...
(btf_finish): ...this.
* ctfc.h: Analogous changes.
* dwarf2ctf.cc (ctf_debug_early_finish): Conditionally call
btf_early_finish, or ctf_finalize as appropriate.  Emit BTF
here for LTO builds.
(ctf_debug_finish): Always call btf_finish here if generating
BTF info in non-LTO builds.
(ctf_debug_finalize, ctf_debug_init_postprocess): Delete.
* dwarf2out.cc (dwarf2out_early_finish): Remove call to
ctf_debug_init_postprocess.

Diff:
---
 gcc/btfout.cc| 28 
 gcc/ctfc.h   |  4 ++--
 gcc/dwarf2ctf.cc | 65 +---
 gcc/dwarf2out.cc |  2 --
 4 files changed, 50 insertions(+), 49 deletions(-)

diff --git a/gcc/btfout.cc b/gcc/btfout.cc
index 07f066a4706..d5e9f3bd43d 100644
--- a/gcc/btfout.cc
+++ b/gcc/btfout.cc
@@ -1491,6 +1491,34 @@ btf_finalize (void)
   tu_ctfc = NULL;
 }
 
+/* Initial entry point of BTF generation, called at early_finish () after
+   CTF information has possibly been output.  Translate all CTF information
+   to BTF, and do any processing that must be done early, such as creating
+   BTF_KIND_FUNC records.  */
+
+void
+btf_early_finish (void)
+{
+  btf_init_postprocess ();
+}
+
+/* Late entry point for BTF generation, called from dwarf2out_finish ().
+   Complete and emit BTF information.  */
+
+void
+btf_finish (const char * filename)
+{
+  btf_output (filename);
+
+  /* If compiling for BPF with CO-RE info, we cannot deallocate until after the
+ contents of the .BTF.ext section are finalized, which happens very late in
+ BPF backend.  Therefore, the deallocation (i.e. btf_finalize ()) is 
delayed
+ until TARGET_ASM_FILE_END for BPF CO-RE.  */
+  if (!btf_with_core_debuginfo_p ())
+btf_finalize ();
+}
+
+
 /* Traversal function for all BTF_KIND_FUNC type records.  */
 
 bool
diff --git a/gcc/ctfc.h b/gcc/ctfc.h
index fa188bf2f5a..e7bd93901cf 100644
--- a/gcc/ctfc.h
+++ b/gcc/ctfc.h
@@ -384,8 +384,8 @@ extern void ctf_init (void);
 extern void ctf_output (const char * filename);
 extern void ctf_finalize (void);
 
-extern void btf_output (const char * filename);
-extern void btf_init_postprocess (void);
+extern void btf_early_finish (void);
+extern void btf_finish (const char * filename);
 extern void btf_finalize (void);
 
 extern ctf_container_ref ctf_get_tu_ctfc (void);
diff --git a/gcc/dwarf2ctf.cc b/gcc/dwarf2ctf.cc
index dc59569fe56..8f9e2fada9e 100644
--- a/gcc/dwarf2ctf.cc
+++ b/gcc/dwarf2ctf.cc
@@ -933,30 +933,6 @@ gen_ctf_type (ctf_container_ref ctfc, dw_die_ref die)
   return type_id;
 }
 
-/* Prepare for output and write out the CTF debug information.  */
-
-static void
-ctf_debug_finalize (const char *filename, bool btf)
-{
-  if (btf)
-{
-  btf_output (filename);
-  /* btf_finalize when compiling BPF applciations gets deallocated by the
-BPF target in bpf_file_end.  */
-  if (btf_debuginfo_p () && !btf_with_core_debuginfo_p ())
-   btf_finalize ();
-}
-
-  else
-{
-  /* Emit the collected CTF information.  */
-  ctf_output (filename);
-
-  /* Reset the CTF state.  */
-  ctf_finalize ();
-}
-}
-
 bool
 ctf_do_die (dw_die_ref die)
 {
@@ -996,27 +972,27 @@ ctf_debug_init (void)
   add_name_attribute (ctf_unknown_die, "unknown");
 }
 
-/* Preprocess the CTF debug information after initialization.  */
-
-void
-ctf_debug_init_postprocess (bool 

[gcc r15-1788] ctf: use pointers instead of IDs internally

2024-07-02 Thread David Faust via Gcc-cvs
https://gcc.gnu.org/g:36774cec1f8d224e202dd3ca2012dae79d4e8ba9

commit r15-1788-g36774cec1f8d224e202dd3ca2012dae79d4e8ba9
Author: David Faust 
Date:   Thu May 30 14:06:27 2024 -0700

ctf: use pointers instead of IDs internally

This patch replaces all inter-type references in the ctfc internal data
structures with pointers, rather than the references-by-ID which were
used previously.

A couple of small updates in the BPF backend are included to make it
compatible with the change.

This change is only to the in-memory representation of various CTF
structures to make them easier to work with in various cases.  It is
outwardly transparent; there is no change in emitted CTF.

gcc/
* btfout.cc (BTF_VOID_TYPEID, BTF_INIT_TYPEID): Move defines to
include/btf.h.
(btf_dvd_emit_preprocess_cb, btf_emit_preprocess)
(btf_dmd_representable_bitfield_p, btf_asm_array, btf_asm_varent)
(btf_asm_sou_member, btf_asm_func_arg, btf_init_postprocess):
Adapt to structural changes in ctf_* structs.
* ctfc.h (struct ctf_dtdef): Add forward declaration.
(ctf_dtdef_t, ctf_dtdef_ref): Move typedefs earlier.
(struct ctf_arinfo, struct ctf_funcinfo, struct ctf_sliceinfo)
(struct ctf_itype, struct ctf_dmdef, struct ctf_func_arg)
(struct ctf_dvdef): Use pointers instead of type IDs for
references to other types and use typedefs where appropriate.
(struct ctf_dtdef): Add ref_type member.
(ctf_type_exists): Use pointer instead of type ID.
(ctf_add_reftype, ctf_add_enum, ctf_add_slice, ctf_add_float)
(ctf_add_integer, ctf_add_unknown, ctf_add_pointer)
(ctf_add_array, ctf_add_forward, ctf_add_typedef)
(ctf_add_function, ctf_add_sou, ctf_add_enumerator)
(ctf_add_variable): Likewise. Return pointer instead of ID.
(ctf_lookup_tree_type): Return pointer to type instead of ID.
* ctfc.cc: Analogous changes.
* ctfout.cc (ctf_asm_type, ctf_asm_slice, ctf_asm_varent)
(ctf_asm_sou_lmember, ctf_asm_sou_member, ctf_asm_func_arg)
(output_ctf_objt_info): Adapt to changes.
* dwarf2ctf.cc (gen_ctf_type, gen_ctf_void_type)
(gen_ctf_unknown_type, gen_ctf_base_type, gen_ctf_pointer_type)
(gen_ctf_subrange_type, gen_ctf_array_type, gen_ctf_typedef)
(gen_ctf_modifier_type, gen_ctf_sou_type, gen_ctf_function_type)
(gen_ctf_enumeration_type, gen_ctf_variable, gen_ctf_function)
(gen_ctf_type, ctf_do_die): Likewise.
* config/bpf/btfext-out.cc (struct btf_ext_core_reloc): Use
pointer instead of type ID.
(bpf_core_reloc_add, bpf_core_get_sou_member_index)
(output_btfext_core_sections): Adapt to above changes.
* config/bpf/core-builtins.cc (process_type): Likewise.

include/
* btf.h (BTF_VOID_TYPEID, BTF_INIT_TYPEID): Move defines here,
from gcc/btfout.cc.

Diff:
---
 gcc/btfout.cc   |  40 +++
 gcc/config/bpf/btfext-out.cc|  14 ++-
 gcc/config/bpf/core-builtins.cc |   3 +-
 gcc/ctfc.cc | 151 +++
 gcc/ctfc.h  |  90 +++---
 gcc/ctfout.cc   |  22 ++--
 gcc/dwarf2ctf.cc| 257 +++-
 include/btf.h   |   5 +
 8 files changed, 290 insertions(+), 292 deletions(-)

diff --git a/gcc/btfout.cc b/gcc/btfout.cc
index d5e9f3bd43d..9d73478ba9a 100644
--- a/gcc/btfout.cc
+++ b/gcc/btfout.cc
@@ -61,11 +61,6 @@ static char btf_info_section_label[MAX_BTF_LABEL_BYTES];
 #define BTF_INFO_SECTION_LABEL  "Lbtf"
 #endif
 
-/* BTF encodes void as type id 0.  */
-
-#define BTF_VOID_TYPEID 0
-#define BTF_INIT_TYPEID 1
-
 #define BTF_INVALID_TYPEID 0x
 
 /* Mapping of CTF variables to the IDs they will be assigned when they are
@@ -626,7 +621,8 @@ btf_dvd_emit_preprocess_cb (ctf_dvdef_ref *slot, 
ctf_container_ref arg_ctfc)
 return 1;
 
   /* Do not add variables which refer to unsupported types.  */
-  if (!voids.contains (var->dvd_type) && btf_removed_type_p (var->dvd_type))
+  if (!voids.contains (var->dvd_type->dtd_type)
+  && btf_removed_type_p (var->dvd_type->dtd_type))
 return 1;
 
   arg_ctfc->ctfc_vars_list[num_vars_added] = var;
@@ -716,7 +712,7 @@ btf_emit_preprocess (ctf_container_ref ctfc)
 static bool
 btf_dmd_representable_bitfield_p (ctf_container_ref ctfc, ctf_dmdef_t *dmd)
 {
-  ctf_dtdef_ref ref_type = ctfc->ctfc_types_list[dmd->dmd_type];
+  ctf_dtdef_ref ref_type = ctfc->ctfc_types_list[dmd->dmd_type->dtd_type];
 
   if (CTF_V2_INFO_KIND (ref_type->dtd_data.ctti_info) == CTF_K_SLICE)
 {
@@ -913,8 +909,8 @@ btf_asm_type (ctf_container_ref ctfc, ctf_dtdef_ref dtd)
 static void
 btf_asm_

[gcc r15-1789] btf: refactor and simplify implementation

2024-07-02 Thread David Faust via Gcc-cvs
https://gcc.gnu.org/g:616c44f02b574b2b6c9dc24b30bb75de8e8b9640

commit r15-1789-g616c44f02b574b2b6c9dc24b30bb75de8e8b9640
Author: David Faust 
Date:   Thu May 30 14:06:27 2024 -0700

btf: refactor and simplify implementation

This patch heavily refactors btfout.cc to take advantage of the
structural changes in the prior commits.

Now that inter-type references are internally stored as simply pointers,
all the painful, brittle, confusing infrastructure that was used in the
process of converting CTF type IDs to BTF type IDs can be thrown out.
This greatly simplifies the entire process of converting from CTF to
BTF, making the code cleaner, easier to read, and easier to maintain.

In addition, we no longer need to worry about destructive changes in
internal data structures used commonly by CTF and BTF, which allows
deleting several ancillary data structures previously used in btfout.cc.

This is nearly transparent, but a few improvements have also been made:

 1) BTF_KIND_FUNC records are now _always_ constructed at early_finish,
allowing us to construct records even for functions which are later
inlined by optimizations. DATASEC entries for functions are only
constructed at late_finish, to avoid incorrectly generating entries
for functions which get inlined.

 2) BTF_KIND_VAR records and DATASEC entries for them are now always
constructed at (late) finish, which avoids cases where we could
incorrectly create records for variables which were completely
optimized away.  This fixes PR debug/113566 for non-LTO builds.
In LTO builds, BTF must be emitted at early_finish, so some VAR
records may be emitted for variables which are later optimized away.

 3) Some additional assembler comments have been added with more
information for debugging.

gcc/
* btfout.cc (struct btf_datasec_entry): New.
(struct btf_datasec): Add `id' member.  Change `entries' to use
new struct btf_datasec_entry.
(func_map): New hash_map.
(max_translated_id): New.
(btf_var_ids, btf_id_map, holes, voids, num_vars_added)
(num_types_added, num_types_created): Delete.
(btf_absolute_var_id, btf_relative_var_id, btf_absolute_func_id)
(btf_relative_func_id, btf_absolute_datasec_id, init_btf_id_map)
(get_btf_id, set_btf_id, btf_emit_id_p): Delete.
(btf_removed_type_p): Delete.
(btf_dtd_kind, btf_emit_type_p): New helpers.
(btf_fwd_to_enum_p, btf_calc_num_vbytes): Use them.
(btf_collect_datasec): Delete.
(btf_dtd_postprocess_cb, btf_dvd_emit_preprocess_cb)
(btf_dtd_emit_preprocess_cb, btf_emit_preprocess): Delete.
(btf_dmd_representable_bitfield_p): Adapt to type reference changes
and delete now-unused ctfc argument.
(btf_asm_datasec_type_ref): Delete.
(btf_asm_type_ref): Adapt to type reference changes, simplify.
(btf_asm_type): Likewise. Mark struct/union types with bitfield
members.
(btf_asm_array): Adapt to data structure changes.
(btf_asm_varent): Likewise.
(btf_asm_sou_member): Likewise. Ensure non-bitfield members are
correctly re-encoded if struct or union contains any bitfield.
(btf_asm_func_arg, btf_asm_func_type, btf_asm_datasec_entry)
(btf_asm_datasec_type): Adapt to data structure changes.
(output_btf_header): Adapt to other changes, simplify type
length calculation, add info to assembler comments.
(output_btf_vars): Adapt to other changes.
(output_btf_strs): Fix overlong lines.
(output_asm_btf_sou_fields, output_asm_btf_enum_list)
(output_asm_btf_func_args_list, output_asm_btf_vlen_bytes)
(output_asm_btf_type, output_btf_types, output_btf_func_types)
(output_btf_datasec_types): Adapt to other changes.
(btf_init_postprocess): Delete.
(btf_output): Change to only perform output.
(btf_add_const_void, btf_add_func_records): New.
(btf_early_finish): Use them here. New.
(btf_datasec_push_entry): Adapt to data structure changes.
(btf_datasec_add_func, btf_datasec_add_var): New.
(btf_add_func_datasec_entries): New.
(btf_emit_variable_p): New helper.
(btf_add_vars): Use it here. New.
(btf_type_list_cb, btf_collect_translated_types): New.
(btf_assign_func_ids, btf_late_assign_var_ids)
(btf_assign_datasec_ids): New.
(btf_finish): Remove unused argument. Call new btf_late*
functions and btf_output.
(btf_finalize): Adapt to data structure changes.
* ctfc.h (struct ct

[gcc r15-1790] btf: add -gprune-btf option

2024-07-02 Thread David Faust via Gcc-cvs
https://gcc.gnu.org/g:b8977d928a7a261913dd89db55d4123b6a54ba46

commit r15-1790-gb8977d928a7a261913dd89db55d4123b6a54ba46
Author: David Faust 
Date:   Mon Jun 10 10:54:53 2024 -0700

btf: add -gprune-btf option

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.

Diff:
---
 gcc/btfout.cc   | 358 +++-
 gcc/common.opt  |   4 +
 gcc/ctfc.cc |   2 +-
 gcc/ctfc.h  |   3 +
 gcc/doc/invoke.texi |  20 ++
 gcc/testsuite/gcc.dg/debug/btf/btf-prune-1.c|  25 ++
 gcc/testsuite/gcc.dg/debug/btf/btf-prune-2.c|  33 +++
 gcc/testsuite/gcc.dg/debug/btf/btf-prune-3.c|  35 +++
 gcc/testsuite/gcc.dg/debug/btf/btf-prune-maps.c |  20 ++
 9 files changed, 493 insertions(+), 7 deletions(-)

diff --git a/gcc/btfout.cc b/gcc/btfout.cc
index 89f148de965..34d8cec0a2e 100644
--- a/gcc/btfout.cc
+++ b/gcc/btfout.cc
@@ -828,7 +828,10 @@ output_btf_types (ctf_container_ref ctfc)
 {
   size_t i;
   size_t num_types;
-  num_types = ctfc->ctfc_types->elements ();
+  if (debug_prune_btf)
+num_types = max_translated_id;
+  else
+num_types = ctfc-

[gcc r15-1791] bpf,btf: enable BTF pruning by default for BPF

2024-07-02 Thread David Faust via Gcc-cvs
https://gcc.gnu.org/g:189d0f1fc2cd2de1815ce5ead8ac87f3cba32010

commit r15-1791-g189d0f1fc2cd2de1815ce5ead8ac87f3cba32010
Author: David Faust 
Date:   Mon Jun 10 10:59:05 2024 -0700

bpf,btf: enable BTF pruning by default for BPF

This patch enables -gprune-btf by default in the BPF backend when
generating BTF information, and fixes BPF CO-RE generation when using
-gprune-btf.

When generating BPF CO-RE information, we must ensure that types used
in CO-RE relocations always have sufficient BTF information emited so
that the CO-RE relocations can be processed by a BPF loader.  The BTF
pruning algorithm on its own does not have sufficient information to
determine which types are used in a BPF CO-RE relocation, so this
information must be supplied by the BPF backend, using a new
btf_mark_type_used function.

Co-authored-by: Cupertino Miranda 

gcc/
* btfout.cc (btf_mark_type_used): New.
* ctfc.h (btf_mark_type_used): Declare it here.
* config/bpf/bpf.cc (bpf_option_override): Enable -gprune-btf
by default if -gbtf is enabled.
* config/bpf/core-builtins.cc (extra_fn): New typedef.
(compute_field_expr): Add callback parameter, and call it if 
supplied.
Fix computation for MEM_REF.
(mark_component_type_as_used): New.
(bpf_mark_types_as_used): Likewise.
(bpf_expand_core_builtin): Call here.
* doc/invoke.texi (Debugging Options): Note that -gprune-btf is
enabled by default for BPF target when generating BTF.

gcc/testsuite/
* gcc.dg/debug/btf/btf-variables-5.c: Adjust one test for bpf-*-*
target.

Diff:
---
 gcc/btfout.cc| 22 
 gcc/config/bpf/bpf.cc|  5 ++
 gcc/config/bpf/core-builtins.cc  | 71 ++--
 gcc/ctfc.h   |  1 +
 gcc/doc/invoke.texi  |  3 +
 gcc/testsuite/gcc.dg/debug/btf/btf-variables-5.c |  6 +-
 6 files changed, 100 insertions(+), 8 deletions(-)

diff --git a/gcc/btfout.cc b/gcc/btfout.cc
index 34d8cec0a2e..083ca48d627 100644
--- a/gcc/btfout.cc
+++ b/gcc/btfout.cc
@@ -1503,6 +1503,28 @@ btf_assign_datasec_ids (ctf_container_ref ctfc)
 }
 }
 
+
+/* Manually mark that type T is used to ensure it will not be pruned.
+   Used by the BPF backend when generating BPF CO-RE to mark types used
+   in CO-RE relocations.  */
+
+void
+btf_mark_type_used (tree t)
+{
+  /* If we are not going to prune anyway, this is a no-op.  */
+  if (!debug_prune_btf)
+return;
+
+  gcc_assert (TYPE_P (t));
+  ctf_container_ref ctfc = ctf_get_tu_ctfc ();
+  ctf_dtdef_ref dtd = ctf_lookup_tree_type (ctfc, t);
+
+  if (!dtd)
+return;
+
+  btf_add_used_type (ctfc, dtd, false, false, true);
+}
+
 /* Callback used for assembling the only-used-types list.  Note that this is
the same as btf_type_list_cb above, but the hash_set traverse requires a
different function signature.  */
diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
index dd1bfe38d29..c62af7a6efa 100644
--- a/gcc/config/bpf/bpf.cc
+++ b/gcc/config/bpf/bpf.cc
@@ -221,6 +221,11 @@ bpf_option_override (void)
   && !(target_flags_explicit & MASK_BPF_CORE))
 target_flags |= MASK_BPF_CORE;
 
+  /* -gbtf implies -gprune-btf for BPF target.  */
+  if (btf_debuginfo_p ())
+SET_OPTION_IF_UNSET (&global_options, &global_options_set,
+debug_prune_btf, true);
+
   /* Determine available features from ISA setting (-mcpu=).  */
   if (bpf_has_jmpext == -1)
 bpf_has_jmpext = (bpf_isa >= ISA_V2);
diff --git a/gcc/config/bpf/core-builtins.cc b/gcc/config/bpf/core-builtins.cc
index 232bebcadbd..86e2e9d6e39 100644
--- a/gcc/config/bpf/core-builtins.cc
+++ b/gcc/config/bpf/core-builtins.cc
@@ -624,13 +624,20 @@ bpf_core_get_index (const tree node, bool *valid)
 
ALLOW_ENTRY_CAST is an input arguments and specifies if the function should
consider as valid expressions in which NODE entry is a cast expression (or
-   tree code nop_expr).  */
+   tree code nop_expr).
+
+   EXTRA_FN is a callback function to allow extra functionality with this
+   function traversal.  Currently used for marking used type during expand
+   pass.  */
+
+typedef void (*extra_fn) (tree);
 
 static unsigned char
 compute_field_expr (tree node, unsigned int *accessors,
bool *valid,
tree *access_node,
-   bool allow_entry_cast = true)
+   bool allow_entry_cast = true,
+   extra_fn callback = NULL)
 {
   unsigned char n = 0;
   unsigned int fake_accessors[MAX_NR_ACCESSORS];
@@ -647,6 +654,9 @@ compute_field_expr (tree node, unsigned int *accessors,
 
   *access_node = node;
 
+  if (callback != NULL)
+callback (node);
+
   switch (TREE_CODE (node))
  

[gcc r15-1792] Regenerate common.opt.urls

2024-07-02 Thread David Faust via Gcc-cvs
https://gcc.gnu.org/g:cc63b59e8843f049587b7a548a530f710085e577

commit r15-1792-gcc63b59e8843f049587b7a548a530f710085e577
Author: David Faust 
Date:   Tue Jul 2 11:39:50 2024 -0700

Regenerate common.opt.urls

I was not aware of the requirement to regenerate the opt urls files
when adding a new option until the autobuilder complained.

Regenerate common.opt.urls for the -gprune-btf option added in:
  b8977d928a7a btf: add -gprune-btf option

gcc/
* common.opt.urls: Regenerate.

Diff:
---
 gcc/common.opt.urls | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/gcc/common.opt.urls b/gcc/common.opt.urls
index 1ec32670633..0e71bce27c4 100644
--- a/gcc/common.opt.urls
+++ b/gcc/common.opt.urls
@@ -1642,6 +1642,9 @@ UrlSuffix(gcc/Debugging-Options.html#index-gctf)
 gbtf
 UrlSuffix(gcc/Debugging-Options.html#index-gbtf)
 
+gprune-btf
+UrlSuffix(gcc/Debugging-Options.html#index-gprune-btf)
+
 gdwarf
 UrlSuffix(gcc/Debugging-Options.html#index-gdwarf)


[gcc r14-9398] bpf: testsuite: fix unresolved test in memset-1.c

2024-03-08 Thread David Faust via Gcc-cvs
https://gcc.gnu.org/g:10c609191c4462133d6a4ea10a739167204f2cd3

commit r14-9398-g10c609191c4462133d6a4ea10a739167204f2cd3
Author: David Faust 
Date:   Thu Mar 7 09:23:38 2024 -0800

bpf: testsuite: fix unresolved test in memset-1.c

The test was trying to do too much by both checking for an error, and
checking the resulting assembly. Of course, due to the error no asm was
produced, so the scan-asm went unresolved. Split it into two separate
tests to fix the issue.

gcc/testsuite/

* gcc.target/bpf/memset-1.c: Move error test case to...
* gcc.target/bpf/memset-2.c: ... here. New test.

Diff:
---
 gcc/testsuite/gcc.target/bpf/memset-1.c |  8 
 gcc/testsuite/gcc.target/bpf/memset-2.c | 22 ++
 2 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/gcc/testsuite/gcc.target/bpf/memset-1.c 
b/gcc/testsuite/gcc.target/bpf/memset-1.c
index 9e9f8eff028..7c4768c6e73 100644
--- a/gcc/testsuite/gcc.target/bpf/memset-1.c
+++ b/gcc/testsuite/gcc.target/bpf/memset-1.c
@@ -28,12 +28,4 @@ set_large (struct context *ctx)
   __builtin_memset (dest, 0xfe, 130);
 }
 
-void
-set_variable (struct context *ctx)
-{
-  void *data = (void *)(long)ctx->data;
-  char *dest = data;
-  __builtin_memset (dest, 0xbc, ctx->data_meta); /* { dg-error "could not 
inline call" } */
-}
-
 /* { dg-final { scan-assembler-times "call" 0 } } */
diff --git a/gcc/testsuite/gcc.target/bpf/memset-2.c 
b/gcc/testsuite/gcc.target/bpf/memset-2.c
new file mode 100644
index 000..0602a1a277c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/memset-2.c
@@ -0,0 +1,22 @@
+/* Test that we error if memset cannot be expanded inline.  */
+
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+struct context {
+ unsigned int data;
+ unsigned int data_end;
+ unsigned int data_meta;
+ unsigned int ingress;
+ unsigned int queue_index;
+ unsigned int egress;
+};
+
+
+void
+set_variable (struct context *ctx)
+{
+  void *data = (void *)(long)ctx->data;
+  char *dest = data;
+  __builtin_memset (dest, 0xbc, ctx->data_meta); /* { dg-error "could not 
inline call" } */
+}


[gcc r14-9400] bpf: add size threshold for inlining mem builtins

2024-03-08 Thread David Faust via Gcc-cvs
https://gcc.gnu.org/g:0e850eff58539fb79483664962fac6c46d65c79d

commit r14-9400-g0e850eff58539fb79483664962fac6c46d65c79d
Author: David Faust 
Date:   Thu Mar 7 09:29:32 2024 -0800

bpf: add size threshold for inlining mem builtins

BPF cannot fall back on library calls to implement memmove, memcpy and
memset, so we attempt to expand these inline always if possible.
However, this inline expansion was being attempted even for excessively
large operations, which could result in gcc consuming huge amounts of
memory and hanging.

Add a size threshold in the BPF backend below which to always expand
these operations inline, and introduce an option
-minline-memops-threshold= to control the threshold. Defaults to
1024 bytes.

gcc/

* config/bpf/bpf.cc (bpf_expand_cpymem, bpf_expand_setmem): Do
not attempt inline expansion if size is above threshold.
* config/bpf/bpf.opt (-minline-memops-threshold): New option.
* doc/invoke.texi (eBPF Options) <-minline-memops-threshold>:
Document.

gcc/testsuite/

* gcc.target/bpf/inline-memops-threshold-1.c: New test.
* gcc.target/bpf/inline-memops-threshold-2.c: New test.

Diff:
---
 gcc/config/bpf/bpf.cc  | 26 +-
 gcc/config/bpf/bpf.opt |  4 
 gcc/doc/invoke.texi| 11 -
 .../gcc.target/bpf/inline-memops-threshold-1.c | 15 +
 .../gcc.target/bpf/inline-memops-threshold-2.c | 11 +
 5 files changed, 65 insertions(+), 2 deletions(-)

diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
index 0e33f4347ba..fb60770c170 100644
--- a/gcc/config/bpf/bpf.cc
+++ b/gcc/config/bpf/bpf.cc
@@ -1244,9 +1244,9 @@ bool
 bpf_expand_cpymem (rtx *operands, bool is_move)
 {
   /* Size must be constant for this expansion to work.  */
+  const char *name = is_move ? "memmove" : "memcpy";
   if (!CONST_INT_P (operands[2]))
 {
-  const char *name = is_move ? "memmove" : "memcpy";
   if (flag_building_libgcc)
warning (0, "could not inline call to %<__builtin_%s%>: "
 "size must be constant", name);
@@ -1275,6 +1275,18 @@ bpf_expand_cpymem (rtx *operands, bool is_move)
   gcc_unreachable ();
 }
 
+  /* For sizes above threshold, always use a libcall.  */
+  if (size_bytes > (unsigned HOST_WIDE_INT) bpf_inline_memops_threshold)
+{
+  if (flag_building_libgcc)
+   warning (0, "could not inline call to %<__builtin_%s%>: "
+"too many bytes, use %<-minline-memops-threshold%>", name);
+  else
+   error ("could not inline call to %<__builtin_%s%>: "
+  "too many bytes, use %<-minline-memops-threshold%>", name);
+  return false;
+}
+
   unsigned iters = size_bytes >> ceil_log2 (align);
   unsigned remainder = size_bytes & (align - 1);
 
@@ -1347,6 +1359,18 @@ bpf_expand_setmem (rtx *operands)
   gcc_unreachable ();
 }
 
+  /* For sizes above threshold, always use a libcall.  */
+  if (size_bytes > (unsigned HOST_WIDE_INT) bpf_inline_memops_threshold)
+{
+  if (flag_building_libgcc)
+   warning (0, "could not inline call to %<__builtin_memset%>: "
+"too many bytes, use %<-minline-memops-threshold%>");
+  else
+   error ("could not inline call to %<__builtin_memset%>: "
+  "too many bytes, use %<-minline-memops-threshold%>");
+  return false;
+}
+
   unsigned iters = size_bytes >> ceil_log2 (align);
   unsigned remainder = size_bytes & (align - 1);
   unsigned inc = GET_MODE_SIZE (mode);
diff --git a/gcc/config/bpf/bpf.opt b/gcc/config/bpf/bpf.opt
index acfddebdad7..541ebe4dfc4 100644
--- a/gcc/config/bpf/bpf.opt
+++ b/gcc/config/bpf/bpf.opt
@@ -108,3 +108,7 @@ Enum(asm_dialect) String(normal) Value(ASM_NORMAL)
 
 EnumValue
 Enum(asm_dialect) String(pseudoc) Value(ASM_PSEUDOC)
+
+minline-memops-threshold=
+Target RejectNegative Joined UInteger Var(bpf_inline_memops_threshold) 
Init(1024)
+-minline-memops-threshold= Maximum size of memset/memmove/memcpy to 
inline, larger sizes will use a library call.
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index c0d604a2c5c..85c938d4a14 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -971,7 +971,7 @@ Objective-C and Objective-C++ Dialects}.
 @gccoptlist{-mbig-endian -mlittle-endian
 -mframe-limit=@var{bytes} -mxbpf -mco-re -mno-co-re -mjmpext
 -mjmp32 -malu32 -mv3-atomics -mbswap -msdiv -msmov -mcpu=@var{version}
--masm=@var{dialect}}
+-masm=@var{dialect} -minline-memops-threshold=@var{bytes}}
 
 @emph{FR30 Options}
 @gccoptlist{-msmall-model  -mno-lsim}
@@ -25701,6 +25701,15 @@ Outputs pseudo-c assembly dialect.
 
 @end table
 
+@opindex -minline-memops-threshold
+@item -minline-memops-threshold=@var{bytes}
+Specifies a size threshold in bytes at or below which memmove, memcpy
+and memset 

[gcc(refs/users/dfaust/heads/gcc-13-bpf)] btf: fix type id in BTF_KIND_FUNC struct data.

2024-03-14 Thread David Faust via Gcc-cvs
https://gcc.gnu.org/g:193966aab3bba1ca27630a23f4b575c53be9af03

commit 193966aab3bba1ca27630a23f4b575c53be9af03
Author: Cupertino Miranda 
Date:   Tue Jan 30 19:01:12 2024 +

btf: fix type id in BTF_KIND_FUNC struct data.

This patch corrects the addition of +1 on the type id, which originally
was done in the wrong location and led to func_dtd->dtd_type for
BTF_KIND_FUNC struct data to contain the type id of the previous entry.

gcc/ChangeLog:

* btfout.cc (btf_collect_dataset): Corrects BTF type id.

(cherry picked from commit 0198cade5ac15c35ed3f5af54060d7bc6a39f326)

Diff:
---
 gcc/btfout.cc | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/gcc/btfout.cc b/gcc/btfout.cc
index 2b087130d58..0c496e49c2d 100644
--- a/gcc/btfout.cc
+++ b/gcc/btfout.cc
@@ -457,7 +457,8 @@ btf_collect_datasec (ctf_container_ref ctfc)
   func_dtd->dtd_data.ctti_type = dtd->dtd_type;
   func_dtd->linkage = dtd->linkage;
   func_dtd->dtd_name = dtd->dtd_name;
-  func_dtd->dtd_type = num_types_added + num_types_created;
+  /* +1 for the sentinel type not in the types map.  */
+  func_dtd->dtd_type = num_types_added + num_types_created + 1;
 
   /* Only the BTF_KIND_FUNC type actually references the name. The
 BTF_KIND_FUNC_PROTO is always anonymous.  */
@@ -480,8 +481,7 @@ btf_collect_datasec (ctf_container_ref ctfc)
 
  struct btf_var_secinfo info;
 
- /* +1 for the sentinel type not in the types map.  */
- info.type = func_dtd->dtd_type + 1;
+ info.type = func_dtd->dtd_type;
 
  /* Both zero at compile time.  */
  info.size = 0;


[gcc(refs/users/dfaust/heads/gcc-13-bpf)] btf: add BTF_KIND_FUNC traversal function.

2024-03-14 Thread David Faust via Gcc-cvs
https://gcc.gnu.org/g:1ab0c08b0885fa7549a635f9bae1422499562fc8

commit 1ab0c08b0885fa7549a635f9bae1422499562fc8
Author: Cupertino Miranda 
Date:   Mon Feb 12 17:36:21 2024 +

btf: add BTF_KIND_FUNC traversal function.

The patch adds a traversal function to traverse all BTF_KIND_FUNC nodes
with a callback function. Used for .BTF.ext section content creation.

gcc/ChangeLog:

* btfout.cc (output_btf_func_types): Use FOR_EACH_VEC_ELT.
(traverse_btf_func_types): Define function.
* ctfc.h (funcs_traverse_callback): Typedef for function
prototype.
(traverse_btf_func_types): Add prototype.

(cherry picked from commit 69a3ce49bda929e1ffbc1fc1123f5f2485ec944d)

Diff:
---
 gcc/btfout.cc | 22 --
 gcc/ctfc.h|  3 +++
 2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/gcc/btfout.cc b/gcc/btfout.cc
index 0c496e49c2d..0cc0f84a4a8 100644
--- a/gcc/btfout.cc
+++ b/gcc/btfout.cc
@@ -1276,8 +1276,10 @@ output_btf_types (ctf_container_ref ctfc)
 static void
 output_btf_func_types (ctf_container_ref ctfc)
 {
-  for (size_t i = 0; i < vec_safe_length (funcs); i++)
-btf_asm_func_type (ctfc, (*funcs)[i], i);
+  ctf_dtdef_ref ref;
+  unsigned i;
+  FOR_EACH_VEC_ELT (*funcs, i, ref)
+btf_asm_func_type (ctfc, ref, i);
 }
 
 /* Output all BTF_KIND_DATASEC records.  */
@@ -1452,4 +1454,20 @@ btf_finalize (void)
   tu_ctfc = NULL;
 }
 
+/* Traversal function for all BTF_KIND_FUNC type records.  */
+
+bool
+traverse_btf_func_types (funcs_traverse_callback callback, void *data)
+{
+  ctf_dtdef_ref ref;
+  unsigned i;
+  FOR_EACH_VEC_ELT (*funcs, i, ref)
+{
+  bool stop = callback (ref, data);
+  if (stop == true)
+   return true;
+}
+  return false;
+}
+
 #include "gt-btfout.h"
diff --git a/gcc/ctfc.h b/gcc/ctfc.h
index bf1841a7fcb..4034ca861b1 100644
--- a/gcc/ctfc.h
+++ b/gcc/ctfc.h
@@ -441,6 +441,9 @@ extern int ctf_add_variable (ctf_container_ref, const char 
*, ctf_id_t,
 extern ctf_id_t ctf_lookup_tree_type (ctf_container_ref, const tree);
 extern ctf_id_t get_btf_id (ctf_id_t);
 
+typedef bool (*funcs_traverse_callback) (ctf_dtdef_ref, void *);
+bool traverse_btf_func_types (funcs_traverse_callback, void *);
+
 /* CTF section does not emit location information; at this time, location
information is needed for BTF CO-RE use-cases.  */


[gcc(refs/users/dfaust/heads/gcc-13-bpf)] bpf: Always emit .BTF.ext section if generating BTF

2024-03-14 Thread David Faust via Gcc-cvs
https://gcc.gnu.org/g:4583f84ba8e6729079e4ca5f745b4ebc58b27ab5

commit 4583f84ba8e6729079e4ca5f745b4ebc58b27ab5
Author: Cupertino Miranda 
Date:   Mon Feb 12 17:37:37 2024 +

bpf: Always emit .BTF.ext section if generating BTF

BPF applications, when generating BTF information should always create a
.BTF.ext section.
Current implementation was only creating it when -mco-re option was used.
This patch makes .BTF.ext always be generated for BPF target objects.
The patch also adds conditions around btf_finalize function call
such that BTF deallocation happens later for BPF target.
For BPF, btf_finalize is only called after .BTF.ext is generated.

gcc/ChangeLog:

* config/bpf/bpf.cc (bpf_option_override): Make .BTF.ext
enabled by default for BPF.
(bpf_file_end): Call BTF deallocation.
(bpf_asm_init_sections): Correct condition.
* dwarf2ctf.cc (ctf_debug_finalize): Conditionally execute BTF
deallocation.
(ctf_debuf_finish): Correct condition for calling
ctf_debug_finalize.

(cherry picked from commit 38d2eb337b41e9cdc5eb89ab865d74ef5304bc03)

Diff:
---
 gcc/config/bpf/bpf.cc | 20 +---
 gcc/dwarf2ctf.cc  | 12 ++--
 2 files changed, 15 insertions(+), 17 deletions(-)

diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
index 394be5f961f..89d3b6b8dfd 100644
--- a/gcc/config/bpf/bpf.cc
+++ b/gcc/config/bpf/bpf.cc
@@ -197,10 +197,8 @@ bpf_option_override (void)
   if (TARGET_BPF_CORE && !btf_debuginfo_p ())
 error ("BPF CO-RE requires BTF debugging information, use %<-gbtf%>");
 
-  /* To support the portability needs of BPF CO-RE approach, BTF debug
- information includes the BPF CO-RE relocations.  */
-  if (TARGET_BPF_CORE)
-write_symbols |= BTF_WITH_CORE_DEBUG;
+  /* BPF applications always generate .BTF.ext.  */
+  write_symbols |= BTF_WITH_CORE_DEBUG;
 
   /* Unlike much of the other BTF debug information, the information necessary
  for CO-RE relocations is added to the CTF container by the BPF backend.
@@ -220,10 +218,7 @@ bpf_option_override (void)
   /* -gbtf implies -mcore when using the BPF backend, unless -mno-co-re
  is specified.  */
   if (btf_debuginfo_p () && !(target_flags_explicit & MASK_BPF_CORE))
-{
-  target_flags |= MASK_BPF_CORE;
-  write_symbols |= BTF_WITH_CORE_DEBUG;
-}
+target_flags |= MASK_BPF_CORE;
 
   /* Determine available features from ISA setting (-mcpu=).  */
   if (bpf_has_jmpext == -1)
@@ -268,7 +263,7 @@ bpf_option_override (void)
 static void
 bpf_asm_init_sections (void)
 {
-  if (TARGET_BPF_CORE)
+  if (btf_debuginfo_p () && btf_with_core_debuginfo_p ())
 btf_ext_init ();
 }
 
@@ -280,8 +275,11 @@ bpf_asm_init_sections (void)
 static void
 bpf_file_end (void)
 {
-  if (TARGET_BPF_CORE)
-btf_ext_output ();
+  if (btf_debuginfo_p () && btf_with_core_debuginfo_p ())
+{
+  btf_ext_output ();
+  btf_finalize ();
+}
 }
 
 #undef TARGET_ASM_FILE_END
diff --git a/gcc/dwarf2ctf.cc b/gcc/dwarf2ctf.cc
index b2945713036..02431602af3 100644
--- a/gcc/dwarf2ctf.cc
+++ b/gcc/dwarf2ctf.cc
@@ -944,7 +944,10 @@ ctf_debug_finalize (const char *filename, bool btf)
   if (btf)
 {
   btf_output (filename);
-  btf_finalize ();
+  /* btf_finalize when compiling BPF applciations gets deallocated by the
+BPF target in bpf_file_end.  */
+  if (btf_debuginfo_p () && !btf_with_core_debuginfo_p ())
+   btf_finalize ();
 }
 
   else
@@ -1027,11 +1030,8 @@ ctf_debug_finish (const char * filename)
   /* Emit BTF debug info here when CO-RE relocations need to be generated.
  BTF with CO-RE relocations needs to be generated when CO-RE is in effect
  for the BPF target.  */
-  if (btf_with_core_debuginfo_p ())
-{
-  gcc_assert (btf_debuginfo_p ());
-  ctf_debug_finalize (filename, btf_debuginfo_p ());
-}
+  if (btf_debuginfo_p () && btf_with_core_debuginfo_p ())
+ctf_debug_finalize (filename, btf_debuginfo_p ());
 }
 
 #include "gt-dwarf2ctf.h"


[gcc(refs/users/dfaust/heads/gcc-13-bpf)] bpf: implementation of func_info in .BTF.ext.

2024-03-14 Thread David Faust via Gcc-cvs
https://gcc.gnu.org/g:ab9ca7ee0825823e24048a1c213ef2dc587d6bc7

commit ab9ca7ee0825823e24048a1c213ef2dc587d6bc7
Author: Cupertino Miranda 
Date:   Mon Feb 12 17:46:03 2024 +

bpf: implementation of func_info in .BTF.ext.

Kernel verifier complains in some particular cases for missing func_info
implementation in .BTF.ext. This patch implements it.

Strings are cached locally in coreout.cc to avoid adding duplicated
strings in the string list. This string deduplication should eventually
be moved to the CTFC functions such that this happens widely.

With this implementation, the CO-RE relocations information was also
simplified and integrated with the FuncInfo structures.

gcc/Changelog:

PR target/113453
* config/bpf/bpf.cc (bpf_function_prologue): Define target
hook.
* config/bpf/coreout.cc (brf_ext_info_section)
(btf_ext_info): Move from coreout.h
(btf_ext_funcinfo, btf_ext_lineinfo): Add struct.
(bpf_core_reloc): Rename to btf_ext_core_reloc.
(btf_ext): Add static variable.
(btfext_info_sec_find_or_add, SEARCH_NODE_AND_RETURN)
(bpf_create_or_find_funcinfo, bpt_create_core_reloc)
(btf_ext_add_string, btf_funcinfo_type_callback)
(btf_add_func_info_for, btf_validate_funcinfo)
(btf_ext_info_len, output_btfext_func_info): Add function.
(output_btfext_header, bpf_core_reloc_add)
(output_btfext_core_relocs, btf_ext_init, btf_ext_output):
Change to support new structs.
* config/bpf/coreout.h (btf_ext_funcinfo, btf_ext_lineinfo):
Move and change in coreout.cc.
(btf_add_func_info_for, btf_ext_add_string): Add prototypes.

gcc/testsuite/ChangeLog:
PR target/113453
* gcc.target/bpf/btfext-funcinfo-nocore.c: Add.
* gcc.target/bpf/btfext-funcinfo.c: Add.
* gcc.target/bpf/core-attr-5.c: Fix regexp.
* gcc.target/bpf/core-attr-6.c: Fix regexp.
* gcc.target/bpf/core-builtin-fieldinfo-offset-1.c: Fix regexp.
* gcc.target/bpf/core-section-1.c: Fix regexp.

(cherry picked from commit 77142bdba485057550c5d849864948b0d20be8af)

Diff:
---
 gcc/config/bpf/bpf.cc  |  12 +
 gcc/config/bpf/coreout.cc  | 514 +++--
 gcc/config/bpf/coreout.h   |  20 +-
 .../gcc.target/bpf/btfext-funcinfo-nocore.c|  42 ++
 gcc/testsuite/gcc.target/bpf/btfext-funcinfo.c |  46 ++
 gcc/testsuite/gcc.target/bpf/core-attr-5.c |   9 +-
 gcc/testsuite/gcc.target/bpf/core-attr-6.c |   6 +-
 .../bpf/core-builtin-fieldinfo-offset-1.c  |  13 +-
 gcc/testsuite/gcc.target/bpf/core-section-1.c  |   2 +-
 9 files changed, 502 insertions(+), 162 deletions(-)

diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
index 89d3b6b8dfd..233025aac95 100644
--- a/gcc/config/bpf/bpf.cc
+++ b/gcc/config/bpf/bpf.cc
@@ -386,6 +386,18 @@ bpf_compute_frame_layout (void)
 #undef TARGET_COMPUTE_FRAME_LAYOUT
 #define TARGET_COMPUTE_FRAME_LAYOUT bpf_compute_frame_layout
 
+/* Defined to initialize data for func_info region in .BTF.ext section.  */
+
+static void
+bpf_function_prologue (FILE *f ATTRIBUTE_UNUSED)
+{
+  if (btf_debuginfo_p ())
+btf_add_func_info_for (cfun->decl, current_function_func_begin_label);
+}
+
+#undef TARGET_ASM_FUNCTION_PROLOGUE
+#define TARGET_ASM_FUNCTION_PROLOGUE bpf_function_prologue
+
 /* Expand to the instructions in a function prologue.  This function
is called when expanding the 'prologue' pattern in bpf.md.  */
 
diff --git a/gcc/config/bpf/coreout.cc b/gcc/config/bpf/coreout.cc
index 0c5d166298f..7ac7f8bdde1 100644
--- a/gcc/config/bpf/coreout.cc
+++ b/gcc/config/bpf/coreout.cc
@@ -31,6 +31,7 @@
 #include "btf.h"
 #include "rtl.h"
 #include "tree-pretty-print.h"
+#include "cgraph.h"
 
 #include "coreout.h"
 
@@ -95,64 +96,193 @@
result, a single .BTF.ext section can contain CO-RE relocations for multiple
programs in distinct sections.  */
 
-/* Internal representation of a BPF CO-RE relocation record.  */
+/* BTF.ext debug info section.  */
+static GTY (()) section * btf_ext_info_section;
+
+#ifndef BTF_EXT_INFO_SECTION_NAME
+#define BTF_EXT_INFO_SECTION_NAME ".BTF.ext"
+#endif
+#define BTF_EXT_INFO_SECTION_FLAGS (SECTION_DEBUG)
+
+#ifndef BTF_EXT_INFO_SECTION_LABEL
+#define BTF_EXT_INFO_SECTION_LABEL "Lbtfext"
+#endif
+
+#define MAX_BTF_EXT_LABEL_BYTES 40
+static char btf_ext_info_section_label[MAX_BTF_EXT_LABEL_BYTES];
+
+/* A funcinfo record, in the .BTF.ext funcinfo section.  */
+struct GTY ((chain_next ("%h.next"))) btf_ext_funcinfo
+{
+  uint32_t type; /* Type ID of a BTF_KIND_FUNC type.  */
+  const char *fnname;
+  const char *label;
+
+  struct btf_ext_funcinfo *next; /* Linked list to collect func_info elems.

[gcc(refs/users/dfaust/heads/gcc-13-bpf)] bpf: renames coreout.* files to btfext-out.*.

2024-03-14 Thread David Faust via Gcc-cvs
https://gcc.gnu.org/g:5cb3615ed932faa521e2587c047b0771816c14aa

commit 5cb3615ed932faa521e2587c047b0771816c14aa
Author: Cupertino Miranda 
Date:   Mon Feb 12 17:56:04 2024 +

bpf: renames coreout.* files to btfext-out.*.

gcc/ChangeLog:

* config.gcc (target_gtfiles): Change coreout to btfext-out.
(extra_objs): Change coreout to btfext-out.
* config/bpf/coreout.cc: Rename to btfext-out.cc.
* config/bpf/btfext-out.cc: Add.
* config/bpf/coreout.h: Rename to btfext-out.h.
* config/bpf/btfext-out.h: Add.
* config/bpf/core-builtins.cc: Change include.
* config/bpf/core-builtins.h: Change include.
* config/bpf/t-bpf: Accomodate renamed files.

(cherry picked from commit 13914f4be9d7d4ac075e780b7a4bd8bac2ca1f15)

Diff:
---
 gcc/config.gcc   | 4 ++--
 gcc/config/bpf/{coreout.cc => btfext-out.cc} | 4 ++--
 gcc/config/bpf/{coreout.h => btfext-out.h}   | 2 +-
 gcc/config/bpf/core-builtins.cc  | 2 +-
 gcc/config/bpf/core-builtins.h   | 2 +-
 gcc/config/bpf/t-bpf | 4 ++--
 6 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/gcc/config.gcc b/gcc/config.gcc
index db5de8f034b..36388e0e4cc 100644
--- a/gcc/config.gcc
+++ b/gcc/config.gcc
@@ -1594,8 +1594,8 @@ bpf-*-*)
 tmake_file="${tmake_file} bpf/t-bpf"
 use_collect2=no
 use_gcc_stdint=provide
-extra_objs="coreout.o core-builtins.o"
-target_gtfiles="$target_gtfiles \$(srcdir)/config/bpf/coreout.cc 
\$(srcdir)/config/bpf/core-builtins.cc"
+extra_objs="btfext-out.o core-builtins.o"
+target_gtfiles="$target_gtfiles \$(srcdir)/config/bpf/btfext-out.cc 
\$(srcdir)/config/bpf/core-builtins.cc"
 ;;
 cris-*-elf | cris-*-none)
tm_file="elfos.h newlib-stdint.h ${tm_file}"
diff --git a/gcc/config/bpf/coreout.cc b/gcc/config/bpf/btfext-out.cc
similarity index 99%
rename from gcc/config/bpf/coreout.cc
rename to gcc/config/bpf/btfext-out.cc
index 7ac7f8bdde1..7b7b0a9c8c2 100644
--- a/gcc/config/bpf/coreout.cc
+++ b/gcc/config/bpf/btfext-out.cc
@@ -33,7 +33,7 @@
 #include "tree-pretty-print.h"
 #include "cgraph.h"
 
-#include "coreout.h"
+#include "btfext-out.h"
 
 /* This file contains data structures and routines for construction and output
of BPF Compile Once - Run Everywhere (BPF CO-RE) information.
@@ -614,4 +614,4 @@ btf_ext_output (void)
   dw2_asm_output_data (4, 0, "Required padding by libbpf structs");
 }
 
-#include "gt-coreout.h"
+#include "gt-btfext-out.h"
diff --git a/gcc/config/bpf/coreout.h b/gcc/config/bpf/btfext-out.h
similarity index 98%
rename from gcc/config/bpf/coreout.h
rename to gcc/config/bpf/btfext-out.h
index e909344bee8..5dbbdc04a1a 100644
--- a/gcc/config/bpf/coreout.h
+++ b/gcc/config/bpf/btfext-out.h
@@ -1,4 +1,4 @@
-/* coreout.h - Declarations and definitions related to
+/* btfext-out.h - Declarations and definitions related to
BPF Compile Once - Run Everywhere (CO-RE) support.
Copyright (C) 2021-2023 Free Software Foundation, Inc.
 
diff --git a/gcc/config/bpf/core-builtins.cc b/gcc/config/bpf/core-builtins.cc
index 1376c930903..570306974a0 100644
--- a/gcc/config/bpf/core-builtins.cc
+++ b/gcc/config/bpf/core-builtins.cc
@@ -45,7 +45,7 @@ along with GCC; see the file COPYING3.  If not see
 
 #include "ctfc.h"
 #include "btf.h"
-#include "coreout.h"
+#include "btfext-out.h"
 #include "core-builtins.h"
 
 /* BPF CO-RE builtins definition.
diff --git a/gcc/config/bpf/core-builtins.h b/gcc/config/bpf/core-builtins.h
index c54f6ddac81..e56b55b94e0 100644
--- a/gcc/config/bpf/core-builtins.h
+++ b/gcc/config/bpf/core-builtins.h
@@ -1,7 +1,7 @@
 #ifndef BPF_CORE_BUILTINS_H
 #define BPF_CORE_BUILTINS_H
 
-#include "coreout.h"
+#include "btfext-out.h"
 
 enum bpf_builtins
 {
diff --git a/gcc/config/bpf/t-bpf b/gcc/config/bpf/t-bpf
index 18f1fa67794..dc50332350c 100644
--- a/gcc/config/bpf/t-bpf
+++ b/gcc/config/bpf/t-bpf
@@ -1,7 +1,7 @@
 
-TM_H += $(srcdir)/config/bpf/coreout.h $(srcdir)/config/bpf/core-builtins.h
+TM_H += $(srcdir)/config/bpf/btfext-out.h $(srcdir)/config/bpf/core-builtins.h
 
-coreout.o: $(srcdir)/config/bpf/coreout.cc
+btfext-out.o: $(srcdir)/config/bpf/btfext-out.cc
$(COMPILE) $<
$(POSTCOMPILE)


[gcc(refs/users/dfaust/heads/gcc-13-bpf)] bpf: add inline memset expansion

2024-03-14 Thread David Faust via Gcc-cvs
https://gcc.gnu.org/g:548dbf6f87878800f214982e6c6d104b8a2a6ea1

commit 548dbf6f87878800f214982e6c6d104b8a2a6ea1
Author: David Faust 
Date:   Mon Mar 4 09:35:01 2024 -0800

bpf: add inline memset expansion

Similar to memmove and memcpy, the BPF backend cannot fall back on a
library call to implement __builtin_memset, and should always expand
calls to it inline if possible.

This patch implements simple inline expansion of memset in the BPF
backend in a verifier-friendly way. Similar to memcpy and memmove, the
size must be an integer constant, as is also required by clang.

gcc/
* config/bpf/bpf-protos.h (bpf_expand_setmem): New prototype.
* config/bpf/bpf.cc (bpf_expand_setmem): New.
* config/bpf/bpf.md (setmemdi): New define_expand.

gcc/testsuite/
* gcc.target/bpf/memset-1.c: New test.

(cherry picked from commit eae6b63b5b5426f943f58b5ae0bf0a6068ca8ad6)

Diff:
---
 gcc/config/bpf/bpf-protos.h |  1 +
 gcc/config/bpf/bpf.cc   | 66 +
 gcc/config/bpf/bpf.md   | 17 +
 gcc/testsuite/gcc.target/bpf/memset-1.c | 39 +++
 4 files changed, 123 insertions(+)

diff --git a/gcc/config/bpf/bpf-protos.h b/gcc/config/bpf/bpf-protos.h
index 3b63b18857c..876569ab645 100644
--- a/gcc/config/bpf/bpf-protos.h
+++ b/gcc/config/bpf/bpf-protos.h
@@ -36,5 +36,6 @@ class gimple_opt_pass;
 gimple_opt_pass *make_pass_lower_bpf_core (gcc::context *ctxt);
 
 bool bpf_expand_cpymem (rtx *, bool);
+bool bpf_expand_setmem (rtx *);
 
 #endif /* ! GCC_BPF_PROTOS_H */
diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
index 233025aac95..c008a961e51 100644
--- a/gcc/config/bpf/bpf.cc
+++ b/gcc/config/bpf/bpf.cc
@@ -1309,6 +1309,72 @@ bpf_expand_cpymem (rtx *operands, bool is_move)
   return true;
 }
 
+/* Expand setmem, as from __builtin_memset.
+   OPERANDS are the same as the setmem pattern.
+   Return true if the expansion was successful, false otherwise.  */
+
+bool
+bpf_expand_setmem (rtx *operands)
+{
+  /* Size must be constant for this expansion to work.  */
+  if (!CONST_INT_P (operands[1]))
+{
+  if (flag_building_libgcc)
+   warning (0, "could not inline call to %<__builtin_memset%>: "
+"size must be constant");
+  else
+   error ("could not inline call to %<__builtin_memset%>: "
+  "size must be constant");
+  return false;
+}
+
+  /* Alignment is a CONST_INT.  */
+  gcc_assert (CONST_INT_P (operands[3]));
+
+  rtx dst = operands[0];
+  rtx size = operands[1];
+  rtx val = operands[2];
+  unsigned HOST_WIDE_INT size_bytes = UINTVAL (size);
+  unsigned align = UINTVAL (operands[3]);
+  enum machine_mode mode;
+  switch (align)
+{
+case 1: mode = QImode; break;
+case 2: mode = HImode; break;
+case 4: mode = SImode; break;
+case 8: mode = DImode; break;
+default:
+  gcc_unreachable ();
+}
+
+  unsigned iters = size_bytes >> ceil_log2 (align);
+  unsigned remainder = size_bytes & (align - 1);
+  unsigned inc = GET_MODE_SIZE (mode);
+  unsigned offset = 0;
+
+  for (unsigned int i = 0; i < iters; i++)
+{
+  emit_move_insn (adjust_address (dst, mode, offset), val);
+  offset += inc;
+}
+  if (remainder & 4)
+{
+  emit_move_insn (adjust_address (dst, SImode, offset), val);
+  offset += 4;
+  remainder -= 4;
+}
+  if (remainder & 2)
+{
+  emit_move_insn (adjust_address (dst, HImode, offset), val);
+  offset += 2;
+  remainder -= 2;
+}
+  if (remainder & 1)
+emit_move_insn (adjust_address (dst, QImode, offset), val);
+
+  return true;
+}
+
 /* Finally, build the GCC target.  */
 
 struct gcc_target targetm = TARGET_INITIALIZER;
diff --git a/gcc/config/bpf/bpf.md b/gcc/config/bpf/bpf.md
index c467bff85b7..1b3cc5c9f6f 100644
--- a/gcc/config/bpf/bpf.md
+++ b/gcc/config/bpf/bpf.md
@@ -663,4 +663,21 @@
   FAIL;
 })
 
+;; memset
+;; 0 is dst
+;; 1 is length
+;; 2 is value
+;; 3 is alignment
+(define_expand "setmemdi"
+  [(set (match_operand:BLK 0 "memory_operand")
+   (match_operand:QI  2 "nonmemory_operand"))
+   (use (match_operand:DI  1 "general_operand"))
+   (match_operand 3 "immediate_operand")]
+ ""
+ {
+  if (bpf_expand_setmem (operands))
+DONE;
+  FAIL;
+})
+
 (include "atomic.md")
diff --git a/gcc/testsuite/gcc.target/bpf/memset-1.c 
b/gcc/testsuite/gcc.target/bpf/memset-1.c
new file mode 100644
index 000..9e9f8eff028
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/memset-1.c
@@ -0,0 +1,39 @@
+/* Ensure memset is expanded inline rather than emitting a libcall.  */
+
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+struct context {
+ unsigned int data;
+ unsigned int data_end;
+ unsigned int data_meta;
+ unsigned int ingress;
+ unsigned int queue_index;
+ unsigned int egress;
+};
+
+void
+set_small (struct context *ctx)
+{
+  void *data = (void *)(long)

[gcc(refs/users/dfaust/heads/gcc-13-bpf)] ctf: fix incorrect CTF for multi-dimensional array types

2024-03-14 Thread David Faust via Gcc-cvs
https://gcc.gnu.org/g:f2cd7e1cb3d326ceb5af3e4629f1ab19dabe6d3f

commit f2cd7e1cb3d326ceb5af3e4629f1ab19dabe6d3f
Author: Cupertino Miranda 
Date:   Thu Feb 29 10:56:13 2024 -0800

ctf: fix incorrect CTF for multi-dimensional array types

PR debug/114186

DWARF DIEs of type DW_TAG_subrange_type are linked together to represent
the information about the subsequent dimensions.  The CTF processing was
so far working through them in the opposite (incorrect) order.

While fixing the issue, refactor the code a bit for readability.

co-authored-By: Indu Bhagat 

gcc/
PR debug/114186
* dwarf2ctf.cc (gen_ctf_array_type): Invoke the ctf_add_array ()
in the correct order of the dimensions.
(gen_ctf_subrange_type): Refactor out handling of
DW_TAG_subrange_type DIE to here.

gcc/testsuite/
PR debug/114186
* gcc.dg/debug/ctf/ctf-array-6.c: Add test.

(cherry picked from commit 5d24bf3afd1bea3e51b87fb7ff24c21e29913999)

Diff:
---
 gcc/dwarf2ctf.cc | 158 +--
 gcc/testsuite/gcc.dg/debug/ctf/ctf-array-6.c |  14 +++
 2 files changed, 89 insertions(+), 83 deletions(-)

diff --git a/gcc/dwarf2ctf.cc b/gcc/dwarf2ctf.cc
index 02431602af3..7cbfe9a9b53 100644
--- a/gcc/dwarf2ctf.cc
+++ b/gcc/dwarf2ctf.cc
@@ -349,105 +349,97 @@ gen_ctf_pointer_type (ctf_container_ref ctfc, dw_die_ref 
ptr_type)
   return ptr_type_id;
 }
 
-/* Generate CTF for an array type.  */
+/* Recursively generate CTF for array dimensions starting at DIE C (of type
+   DW_TAG_subrange_type) until DIE LAST (of type DW_TAG_subrange_type) is
+   reached.  ARRAY_ELEMS_TYPE_ID is base type for the array.  */
 
 static ctf_id_t
-gen_ctf_array_type (ctf_container_ref ctfc, dw_die_ref array_type)
+gen_ctf_subrange_type (ctf_container_ref ctfc, ctf_id_t array_elems_type_id,
+  dw_die_ref c, dw_die_ref last)
 {
-  dw_die_ref c;
-  ctf_id_t array_elems_type_id = CTF_NULL_TYPEID;
+  ctf_arinfo_t arinfo;
+  ctf_id_t array_node_type_id = CTF_NULL_TYPEID;
 
-  int vector_type_p = get_AT_flag (array_type, DW_AT_GNU_vector);
-  if (vector_type_p)
-return array_elems_type_id;
+  dw_attr_node *upper_bound_at;
+  dw_die_ref array_index_type;
+  uint32_t array_num_elements;
 
-  dw_die_ref array_elems_type = ctf_get_AT_type (array_type);
+  if (dw_get_die_tag (c) == DW_TAG_subrange_type)
+{
+  /* When DW_AT_upper_bound is used to specify the size of an
+array in DWARF, it is usually an unsigned constant
+specifying the upper bound index of the array.  However,
+for unsized arrays, such as foo[] or bar[0],
+DW_AT_upper_bound is a signed integer constant
+instead.  */
+
+  upper_bound_at = get_AT (c, DW_AT_upper_bound);
+  if (upper_bound_at
+ && AT_class (upper_bound_at) == dw_val_class_unsigned_const)
+   /* This is the upper bound index.  */
+   array_num_elements = get_AT_unsigned (c, DW_AT_upper_bound) + 1;
+  else if (get_AT (c, DW_AT_count))
+   array_num_elements = get_AT_unsigned (c, DW_AT_count);
+  else
+   {
+ /* This is a VLA of some kind.  */
+ array_num_elements = 0;
+   }
+}
+  else
+gcc_unreachable ();
 
-  /* First, register the type of the array elements if needed.  */
-  array_elems_type_id = gen_ctf_type (ctfc, array_elems_type);
+  /* Ok, mount and register the array type.  Note how the array
+ type we register here is the type of the elements in
+ subsequent "dimensions", if there are any.  */
+  arinfo.ctr_nelems = array_num_elements;
 
-  /* DWARF array types pretend C supports multi-dimensional arrays.
- So for the type int[N][M], the array type DIE contains two
- subrange_type children, the first with upper bound N-1 and the
- second with upper bound M-1.
+  array_index_type = ctf_get_AT_type (c);
+  arinfo.ctr_index = gen_ctf_type (ctfc, array_index_type);
 
- CTF, on the other hand, just encodes each array type in its own
- array type CTF struct.  Therefore we have to iterate on the
- children and create all the needed types.  */
+  if (c == last)
+arinfo.ctr_contents = array_elems_type_id;
+  else
+arinfo.ctr_contents = gen_ctf_subrange_type (ctfc, array_elems_type_id,
+dw_get_die_sib (c), last);
 
-  c = dw_get_die_child (array_type);
-  gcc_assert (c);
-  do
-{
-  ctf_arinfo_t arinfo;
-  dw_die_ref array_index_type;
-  uint32_t array_num_elements;
+  if (!ctf_type_exists (ctfc, c, &array_node_type_id))
+array_node_type_id = ctf_add_array (ctfc, CTF_ADD_ROOT, &arinfo, c);
 
-  c = dw_get_die_sib (c);
+  return array_node_type_id;
+}
 
-  if (dw_get_die_tag (c) == DW_TAG_subrange_type)
-   {
- dw_attr_node *upper_bound_at;
-
- array_index_type = ctf_get_AT_type (c);
-
- /* Whe

[gcc(refs/users/dfaust/heads/gcc-13-bpf)] bpf: testsuite: fix unresolved test in memset-1.c

2024-03-14 Thread David Faust via Gcc-cvs
https://gcc.gnu.org/g:64e6da250a07c19d302ec8648824cb42b608cf62

commit 64e6da250a07c19d302ec8648824cb42b608cf62
Author: David Faust 
Date:   Thu Mar 7 09:23:38 2024 -0800

bpf: testsuite: fix unresolved test in memset-1.c

The test was trying to do too much by both checking for an error, and
checking the resulting assembly. Of course, due to the error no asm was
produced, so the scan-asm went unresolved. Split it into two separate
tests to fix the issue.

gcc/testsuite/

* gcc.target/bpf/memset-1.c: Move error test case to...
* gcc.target/bpf/memset-2.c: ... here. New test.

(cherry picked from commit 10c609191c4462133d6a4ea10a739167204f2cd3)

Diff:
---
 gcc/testsuite/gcc.target/bpf/memset-1.c |  8 
 gcc/testsuite/gcc.target/bpf/memset-2.c | 22 ++
 2 files changed, 22 insertions(+), 8 deletions(-)

diff --git a/gcc/testsuite/gcc.target/bpf/memset-1.c 
b/gcc/testsuite/gcc.target/bpf/memset-1.c
index 9e9f8eff028..7c4768c6e73 100644
--- a/gcc/testsuite/gcc.target/bpf/memset-1.c
+++ b/gcc/testsuite/gcc.target/bpf/memset-1.c
@@ -28,12 +28,4 @@ set_large (struct context *ctx)
   __builtin_memset (dest, 0xfe, 130);
 }
 
-void
-set_variable (struct context *ctx)
-{
-  void *data = (void *)(long)ctx->data;
-  char *dest = data;
-  __builtin_memset (dest, 0xbc, ctx->data_meta); /* { dg-error "could not 
inline call" } */
-}
-
 /* { dg-final { scan-assembler-times "call" 0 } } */
diff --git a/gcc/testsuite/gcc.target/bpf/memset-2.c 
b/gcc/testsuite/gcc.target/bpf/memset-2.c
new file mode 100644
index 000..0602a1a277c
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/memset-2.c
@@ -0,0 +1,22 @@
+/* Test that we error if memset cannot be expanded inline.  */
+
+/* { dg-do compile } */
+/* { dg-options "-O2" } */
+
+struct context {
+ unsigned int data;
+ unsigned int data_end;
+ unsigned int data_meta;
+ unsigned int ingress;
+ unsigned int queue_index;
+ unsigned int egress;
+};
+
+
+void
+set_variable (struct context *ctx)
+{
+  void *data = (void *)(long)ctx->data;
+  char *dest = data;
+  __builtin_memset (dest, 0xbc, ctx->data_meta); /* { dg-error "could not 
inline call" } */
+}


[gcc(refs/users/dfaust/heads/gcc-13-bpf)] bpf: add size threshold for inlining mem builtins

2024-03-14 Thread David Faust via Gcc-cvs
https://gcc.gnu.org/g:333445364ba7829dde7a9e8548a26c26eb979c21

commit 333445364ba7829dde7a9e8548a26c26eb979c21
Author: David Faust 
Date:   Thu Mar 7 09:29:32 2024 -0800

bpf: add size threshold for inlining mem builtins

BPF cannot fall back on library calls to implement memmove, memcpy and
memset, so we attempt to expand these inline always if possible.
However, this inline expansion was being attempted even for excessively
large operations, which could result in gcc consuming huge amounts of
memory and hanging.

Add a size threshold in the BPF backend below which to always expand
these operations inline, and introduce an option
-minline-memops-threshold= to control the threshold. Defaults to
1024 bytes.

gcc/

* config/bpf/bpf.cc (bpf_expand_cpymem, bpf_expand_setmem): Do
not attempt inline expansion if size is above threshold.
* config/bpf/bpf.opt (-minline-memops-threshold): New option.
* doc/invoke.texi (eBPF Options) <-minline-memops-threshold>:
Document.

gcc/testsuite/

* gcc.target/bpf/inline-memops-threshold-1.c: New test.
* gcc.target/bpf/inline-memops-threshold-2.c: New test.

(cherry picked from commit 0e850eff58539fb79483664962fac6c46d65c79d)

Diff:
---
 gcc/config/bpf/bpf.cc  | 26 +-
 gcc/config/bpf/bpf.opt |  4 
 gcc/doc/invoke.texi| 11 -
 .../gcc.target/bpf/inline-memops-threshold-1.c | 15 +
 .../gcc.target/bpf/inline-memops-threshold-2.c | 11 +
 5 files changed, 65 insertions(+), 2 deletions(-)

diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
index c008a961e51..83843574029 100644
--- a/gcc/config/bpf/bpf.cc
+++ b/gcc/config/bpf/bpf.cc
@@ -1244,9 +1244,9 @@ bool
 bpf_expand_cpymem (rtx *operands, bool is_move)
 {
   /* Size must be constant for this expansion to work.  */
+  const char *name = is_move ? "memmove" : "memcpy";
   if (!CONST_INT_P (operands[2]))
 {
-  const char *name = is_move ? "memmove" : "memcpy";
   if (flag_building_libgcc)
warning (0, "could not inline call to %<__builtin_%s%>: "
 "size must be constant", name);
@@ -1275,6 +1275,18 @@ bpf_expand_cpymem (rtx *operands, bool is_move)
   gcc_unreachable ();
 }
 
+  /* For sizes above threshold, always use a libcall.  */
+  if (size_bytes > (unsigned HOST_WIDE_INT) bpf_inline_memops_threshold)
+{
+  if (flag_building_libgcc)
+   warning (0, "could not inline call to %<__builtin_%s%>: "
+"too many bytes, use %<-minline-memops-threshold%>", name);
+  else
+   error ("could not inline call to %<__builtin_%s%>: "
+  "too many bytes, use %<-minline-memops-threshold%>", name);
+  return false;
+}
+
   unsigned iters = size_bytes >> ceil_log2 (align);
   unsigned remainder = size_bytes & (align - 1);
 
@@ -1347,6 +1359,18 @@ bpf_expand_setmem (rtx *operands)
   gcc_unreachable ();
 }
 
+  /* For sizes above threshold, always use a libcall.  */
+  if (size_bytes > (unsigned HOST_WIDE_INT) bpf_inline_memops_threshold)
+{
+  if (flag_building_libgcc)
+   warning (0, "could not inline call to %<__builtin_memset%>: "
+"too many bytes, use %<-minline-memops-threshold%>");
+  else
+   error ("could not inline call to %<__builtin_memset%>: "
+  "too many bytes, use %<-minline-memops-threshold%>");
+  return false;
+}
+
   unsigned iters = size_bytes >> ceil_log2 (align);
   unsigned remainder = size_bytes & (align - 1);
   unsigned inc = GET_MODE_SIZE (mode);
diff --git a/gcc/config/bpf/bpf.opt b/gcc/config/bpf/bpf.opt
index efa0380ee3f..ab166bfd865 100644
--- a/gcc/config/bpf/bpf.opt
+++ b/gcc/config/bpf/bpf.opt
@@ -106,3 +106,7 @@ Enum(asm_dialect) String(normal) Value(ASM_NORMAL)
 
 EnumValue
 Enum(asm_dialect) String(pseudoc) Value(ASM_PSEUDOC)
+
+minline-memops-threshold=
+Target RejectNegative Joined UInteger Var(bpf_inline_memops_threshold) 
Init(1024)
+-minline-memops-threshold= Maximum size of memset/memmove/memcpy to 
inline, larger sizes will use a library call.
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
index 999867e9d6d..746ce282f39 100644
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -946,7 +946,7 @@ Objective-C and Objective-C++ Dialects}.
 @gccoptlist{-mbig-endian -mlittle-endian
 -mframe-limit=@var{bytes} -mxbpf -mco-re -mno-co-re -mjmpext
 -mjmp32 -malu32 -mv3-atomics -mbswap -msdiv -msmov -mcpu=@var{version}
--masm=@var{dialect}}
+-masm=@var{dialect} -minline-memops-threshold=@var{bytes}}
 
 @emph{FR30 Options}
 @gccoptlist{-msmall-model  -mno-lsim}
@@ -24620,6 +24620,15 @@ Outputs pseudo-c assembly dialect.
 
 @end table
 
+@opindex -minline-memops-threshold
+@item -minline-memops-threshold=@var{bytes}
+Specifies a si

[gcc(refs/users/dfaust/heads/gcc-13-bpf)] testsuite: ctf: make array in ctf-file-scope-1 fixed length

2024-03-14 Thread David Faust via Gcc-cvs
https://gcc.gnu.org/g:3eae1cdff0cf06bd21b51700e22d443110d0adad

commit 3eae1cdff0cf06bd21b51700e22d443110d0adad
Author: David Faust 
Date:   Fri Mar 1 10:43:24 2024 -0800

testsuite: ctf: make array in ctf-file-scope-1 fixed length

The array member of struct SFOO in the ctf-file-scope-1 caused the test
to fail for the BPF target, since BPF does not support dynamic stack
allocation. The array does not need to variable length for the sake of
the test, so make it fixed length instead to allow the test to run
successfully for the bpf-unknown-none target.

gcc/testsuite/

* gcc.dg/debug/ctf/ctf-file-scope-1.c (SFOO): Make array member
fixed-length.

(cherry picked from commit 64221c7bffbdd399e49554b0fb08b38325657596)

Diff:
---
 gcc/testsuite/gcc.dg/debug/ctf/ctf-file-scope-1.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/testsuite/gcc.dg/debug/ctf/ctf-file-scope-1.c 
b/gcc/testsuite/gcc.dg/debug/ctf/ctf-file-scope-1.c
index a683113e505..ddfb31da405 100644
--- a/gcc/testsuite/gcc.dg/debug/ctf/ctf-file-scope-1.c
+++ b/gcc/testsuite/gcc.dg/debug/ctf/ctf-file-scope-1.c
@@ -9,7 +9,7 @@
 
 int foo (int n)
 {
-  typedef struct { int a[n]; } SFOO;
+  typedef struct { int a[6]; } SFOO;
 
   SFOO a;
   __attribute__ ((noinline)) SFOO gfoo (void) { return a; }


[gcc r14-9481] bpf: define INT8_TYPE as signed char

2024-03-14 Thread David Faust via Gcc-cvs
https://gcc.gnu.org/g:6cf4286ff9456685a29812a3560d00b956d62c39

commit r14-9481-g6cf4286ff9456685a29812a3560d00b956d62c39
Author: David Faust 
Date:   Thu Mar 14 09:05:38 2024 -0700

bpf: define INT8_TYPE as signed char

Change the BPF backend to define INT8_TYPE with an explicit sign, rather
than a plain char.  This is in line with other targets and removes the
risk of int8_t being affected by the signedness of the plain char type
of the host system.

The motivation for this change is that even if `char' is defined to be
signed in BPF targets, some BPF programs use the (mal)practice of
including internal libc headers, either directly or indirectly via
kernel headers, which in turn may trigger compilation errors regarding
redefinitions of types.

gcc/

* config/bpf/bpf.h (INT8_TYPE): Change to signed char.

Diff:
---
 gcc/config/bpf/bpf.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/gcc/config/bpf/bpf.h b/gcc/config/bpf/bpf.h
index f107a5a4c34..3cc5daa1b58 100644
--- a/gcc/config/bpf/bpf.h
+++ b/gcc/config/bpf/bpf.h
@@ -99,7 +99,7 @@
 
 #define SIG_ATOMIC_TYPE "char"
 
-#define INT8_TYPE "char"
+#define INT8_TYPE "signed char"
 #define INT16_TYPE "short int"
 #define INT32_TYPE "int"
 #define INT64_TYPE "long int"


[gcc r14-9876] btf: emit symbol refs in DATASEC entries only for BPF [PR114608]

2024-04-09 Thread David Faust via Gcc-cvs
https://gcc.gnu.org/g:8075477f81ae8d0abf64b80dfbd179151f91b417

commit r14-9876-g8075477f81ae8d0abf64b80dfbd179151f91b417
Author: David Faust 
Date:   Mon Apr 8 11:10:41 2024 -0700

btf: emit symbol refs in DATASEC entries only for BPF [PR114608]

The behavior introduced in
  fa60ac54964 btf: Emit labels in DATASEC bts_offset entries.

is only fully correct when compiling for the BPF target with BPF CO-RE
enabled.  In other cases, depending on optimizations, it can result in
an incorrect symbol reference in the entry bts_offset field for a symbol
which may not be emitted at all, causing link-time undefined symbol
reference errors like in PR114608.

The offending bts_offset field of BTF_KIND_DATASEC entries is in reality
only currently useful to consumers of BTF information for BPF programs
anyway.  Correct the regression by only emitting symbol references in
these entries when compiling for the BPF target.  For other targets, the
behavior returns to that prior to fa60ac54964.

The underlying cause is related to PR 113566 "btf: incorrect
BTF_KIND_DATASEC entries for variables which are optimized out." A
complete fix for 113566 is more involved and unsuitable for stage 4,
but will be addressed in the near future.

gcc/
PR debug/114608
* btfout.cc (btf_asm_datasec_entry): Only emit a symbol reference 
when
generating BTF for BPF CO-RE target.

gcc/testsuite/
PR debug/114608
* gcc.dg/debug/btf/btf-datasec-1.c: Check bts_offset symbol 
references
only for BPF target.
* gcc.dg/debug/btf/btf-datasec-2.c: Likewise.
* gcc.dg/debug/btf/btf-pr106773.c: Likewise.

Diff:
---
 gcc/btfout.cc  |  2 +-
 gcc/testsuite/gcc.dg/debug/btf/btf-datasec-1.c | 10 ++
 gcc/testsuite/gcc.dg/debug/btf/btf-datasec-2.c |  7 ---
 gcc/testsuite/gcc.dg/debug/btf/btf-pr106773.c  |  3 ++-
 4 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/gcc/btfout.cc b/gcc/btfout.cc
index 2e2b3524e83..4a8ec4d1ff0 100644
--- a/gcc/btfout.cc
+++ b/gcc/btfout.cc
@@ -1045,7 +1045,7 @@ btf_asm_datasec_entry (ctf_container_ref ctfc, struct 
btf_var_secinfo info)
 {
   const char *symbol_name = get_name_for_datasec_entry (ctfc, info.type);
   btf_asm_type_ref ("bts_type", ctfc, info.type);
-  if (symbol_name == NULL)
+  if (!btf_with_core_debuginfo_p () || symbol_name == NULL)
 dw2_asm_output_data (4, info.offset, "bts_offset");
   else
 dw2_asm_output_offset (4, symbol_name, NULL, "bts_offset");
diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-1.c 
b/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-1.c
index c8ebe5d07ca..15b76259218 100644
--- a/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-1.c
+++ b/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-1.c
@@ -19,10 +19,12 @@
 /* { dg-final { scan-assembler-times "0xf03\[\t \]+\[^\n\]*btt_info" 2 } } 
*/
 /* { dg-final { scan-assembler-times "0xf01\[\t \]+\[^\n\]*btt_info" 1 } } 
*/
 
-/* The offset entry for each variable in a DATSEC should contain a label.  */
-/* { dg-final { scan-assembler-times 
"(?:(?:\\.4byte|\\.long|data4\\.ua|\\.ualong|\\.uaword|\\.dword|long|dc\\.l|\\.word)\[\t
 \]|\\.vbyte\t4,\[\t \]?)_?\[a-e\]\[\t \]+\[^\n\]*bts_offset" 5 } } */
-/* { dg-final { scan-assembler-times "my_cstruct\[\t \]+\[^\n\]*bts_offset" 1 
} } */
-/* { dg-final { scan-assembler-times "bigarr\[\t \]+\[^\n\]*bts_offset" 1 } } 
*/
+/* { dg-final { scan-assembler-times "0\[\t \]+\[^\n\]*bts_offset" 7 { target 
{ ! bpf-*-* } } } } */
+
+/* For BPF target the offset entry for each variable in a DATSEC should 
contain a label.  */
+/* { dg-final { scan-assembler-times ".4byte\[\t \]\[a-e\]\[\t 
\]+\[^\n\]*bts_offset" 5 { target bpf-*-* } } } */
+/* { dg-final { scan-assembler-times "my_cstruct\[\t \]+\[^\n\]*bts_offset" 1 
{ target bpf-*-* } } } */
+/* { dg-final { scan-assembler-times "bigarr\[\t \]+\[^\n\]*bts_offset" 1 { 
target bpf-*-* } } } */
 
 /* Check that strings for each DATASEC have been added to the BTF string 
table.  */
 /* { dg-final { scan-assembler-times "ascii \".data.0\"\[\t 
\]+\[^\n\]*btf_aux_string" 1 } } */
diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-2.c 
b/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-2.c
index 857d830e446..a89a239a504 100644
--- a/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-2.c
+++ b/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-2.c
@@ -10,9 +10,10 @@
 /* { dg-final { scan-assembler-times " BTF_KIND_DATASEC 
'.bar_sec'\[\\r\\n\]+\[^\\r\\n\]*0xf02\[\t \]+\[^\n\]*btt_info" 1 } } */
 
 /* Function entries should have offset with a label and size of 0 at compile 
time.  */
-/* { dg-final { scan-assembler-times "chacha\[\t \]+\[^\n\]*bts_offset" 1 } } 
*/
-/* { dg-final { scan-assembler-times "bar\[\t \]+\[^\n\]*bts_offset" 1 } } */
-/* { dg-final { scan-assembler-times "foo\[\t \]+\[^\n\]*bts_offset" 1 } } */
+/* { dg-final

[gcc r14-9878] btf: improve btf-datasec-3.c test [PR114642]

2024-04-09 Thread David Faust via Gcc-cvs
https://gcc.gnu.org/g:639215c5eb6c56ba3830cd868d1d3ddd700b4c90

commit r14-9878-g639215c5eb6c56ba3830cd868d1d3ddd700b4c90
Author: David Faust 
Date:   Mon Apr 8 13:33:48 2024 -0700

btf: improve btf-datasec-3.c test [PR114642]

This test failed on powerpc --target_board=unix'{-m32}' because two
variables were not placed in sections where the test silently (and
incorrectly) assumed they would be.

The important thing for the test is only that BTF_KIND_DATASEC entries
are NOT generated for the extern variable declarations without an
explicit section attribute.  Make the test more robust by placing the
non-extern variables in explicit sections, and invert the checks to
more accurately verify what we care about in this test.

gcc/testsuite/
PR testsuite/114642
* gcc.dg/debug/btf/btf-datasec-3.c: Make test more robust on 
different
architectures.

Diff:
---
 gcc/testsuite/gcc.dg/debug/btf/btf-datasec-3.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-3.c 
b/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-3.c
index 297340cabfa..6b127aa14da 100644
--- a/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-3.c
+++ b/gcc/testsuite/gcc.dg/debug/btf/btf-datasec-3.c
@@ -7,22 +7,22 @@
 
 extern int VERSION __attribute__((section (".version")));
 
-extern int test_bss1;
-extern int test_data1;
+extern int ext1;
+extern int ext2;
 
-int test_bss2;
-int test_data2 = 2;
+int var1 __attribute__((section (".sec_a")));
+int var2 __attribute__((section (".sec_b"))) = 2;
 
 int
 foo (void)
 {
-  test_bss2 = VERSION;
-  return test_bss1 + test_data1 + test_data2;
+  ext2 = VERSION;
+  return ext1 + var1 + var2;
 }
 
 /* There should be 3 DATASEC entries total.  Of the extern decls, only VERSION
has a known section; entries are not created for the other two.  */
 /* { dg-final { scan-assembler-times "bts_type" 3 } } */
-/* { dg-final { scan-assembler-times "bts_type: \\(BTF_KIND_VAR 
'test_data2'\\)" 1 } } */
-/* { dg-final { scan-assembler-times "bts_type: \\(BTF_KIND_VAR 
'test_bss2'\\)" 1 } } */
 /* { dg-final { scan-assembler-times "bts_type: \\(BTF_KIND_VAR 'VERSION'\\)" 
1 } } */
+/* { dg-final { scan-assembler-not "bts_type: \\(BTF_KIND_VAR 'ext1'\\)" } } */
+/* { dg-final { scan-assembler-not "bts_type: \\(BTF_KIND_VAR 'ext2'\\)" } } */


[gcc r14-9927] btf: emit non-representable bitfield as void

2024-04-11 Thread David Faust via Gcc-cvs
https://gcc.gnu.org/g:f079d69d7b1338522562516537d96e9e1285c95e

commit r14-9927-gf079d69d7b1338522562516537d96e9e1285c95e
Author: David Faust 
Date:   Thu Apr 11 11:18:55 2024 -0700

btf: emit non-representable bitfield as void

This patch fixes an issue with mangled BTF that could occur when
a struct type contains a bitfield member which cannot be represented
in BTF.  It is undefined what should happen in such cases, but we can
at least do something reasonable.

Commit

  936dd627cd9 "btf: do not skip members of data type with type id
  BTF_VOID_TYPEID"

made a similar change for un-representable non-bitfield members, but
had an unintended side-effect of mangling BTF for un-representable
bitfields: the struct (or union) would account for the offending
bitfield in its member count but the bitfield member itself was
not emitted, making the member count incorrect.

This change ensures that non-representable bitfield members of struct
and union types are always emitted with BTF_VOID_TYPEID.  This avoids
corrupting the BTF information for the entire struct or union type.

gcc/
* btfout.cc (btf_asm_sou_member): Always emit non-representable
bitfield members as having 'void' type.  Refactor slightly.

gcc/testsuite/
* gcc.dg/debug/btf/btf-bitfields-4.c: Add two new checks.

Diff:
---
 gcc/btfout.cc| 54 
 gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-4.c |  2 +
 2 files changed, 28 insertions(+), 28 deletions(-)

diff --git a/gcc/btfout.cc b/gcc/btfout.cc
index ab491f0297f..a1510574a93 100644
--- a/gcc/btfout.cc
+++ b/gcc/btfout.cc
@@ -922,41 +922,39 @@ static void
 btf_asm_sou_member (ctf_container_ref ctfc, ctf_dmdef_t * dmd, unsigned int 
idx)
 {
   ctf_dtdef_ref ref_type = ctfc->ctfc_types_list[dmd->dmd_type];
+  ctf_id_t base_type = get_btf_id (dmd->dmd_type);
+  uint64_t sou_offset = dmd->dmd_offset;
+
+  dw2_asm_output_data (4, dmd->dmd_name_offset,
+  "MEMBER '%s' idx=%u",
+  dmd->dmd_name, idx);
 
   /* Re-encode bitfields to BTF representation.  */
   if (CTF_V2_INFO_KIND (ref_type->dtd_data.ctti_info) == CTF_K_SLICE)
 {
-  ctf_id_t base_type = ref_type->dtd_u.dtu_slice.cts_type;
-  unsigned short word_offset = ref_type->dtd_u.dtu_slice.cts_offset;
-  unsigned short bits = ref_type->dtd_u.dtu_slice.cts_bits;
-  uint64_t sou_offset = dmd->dmd_offset;
-
-  /* Pack the bit offset and bitfield size together.  */
-  sou_offset += word_offset;
-
-  /* If this bitfield cannot be represented, do not output anything.
-The parent struct/union 'vlen' field has already been updated.  */
-  if ((bits > 0xff) || (sou_offset > 0xff))
-   return;
+  if (btf_dmd_representable_bitfield_p (ctfc, dmd))
+   {
+ unsigned short word_offset = ref_type->dtd_u.dtu_slice.cts_offset;
+ unsigned short bits = ref_type->dtd_u.dtu_slice.cts_bits;
 
-  sou_offset &= 0x00ff;
-  sou_offset |= ((bits & 0xff) << 24);
+ /* Pack the bit offset and bitfield size together.  */
+ sou_offset += word_offset;
+ sou_offset &= 0x00ff;
+ sou_offset |= ((bits & 0xff) << 24);
 
-  dw2_asm_output_data (4, dmd->dmd_name_offset,
-  "MEMBER '%s' idx=%u",
-  dmd->dmd_name, idx);
-  /* Refer to the base type of the slice.  */
-  btf_asm_type_ref ("btm_type", ctfc, get_btf_id (base_type));
-  dw2_asm_output_data (4, sou_offset, "btm_offset");
-}
-  else
-{
-  dw2_asm_output_data (4, dmd->dmd_name_offset,
-  "MEMBER '%s' idx=%u",
-  dmd->dmd_name, idx);
-  btf_asm_type_ref ("btm_type", ctfc, get_btf_id (dmd->dmd_type));
-  dw2_asm_output_data (4, dmd->dmd_offset, "btm_offset");
+ /* Refer to the base type of the slice.  */
+ base_type = get_btf_id (ref_type->dtd_u.dtu_slice.cts_type);
+   }
+  else
+   {
+ /* Bitfield cannot be represented in BTF.  Emit the member as having
+'void' type.  */
+ base_type = BTF_VOID_TYPEID;
+   }
 }
+
+  btf_asm_type_ref ("btm_type", ctfc, base_type);
+  dw2_asm_output_data (4, sou_offset, "btm_offset");
 }
 
 /* Asm'out an enum constant following a BTF_KIND_ENUM{,64}.  */
diff --git a/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-4.c 
b/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-4.c
index d4a6ef6a1eb..20cdfaa057a 100644
--- a/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-4.c
+++ b/gcc/testsuite/gcc.dg/debug/btf/btf-bitfields-4.c
@@ -14,6 +14,8 @@
 
 /* Struct with 4 members and no bitfield (kind_flag not set).  */
 /* { dg-final { scan-assembler-times "\[\t \]0x404\[\t 
\]+\[^\n\]*btt_info" 1 } } */
+/* { dg-final { scan-assembler-times " MEMBER" 4 } } */
+/* { dg-final { scan-as

[gcc r14-9928] btf: fix a possibly misleading asm debug comment

2024-04-11 Thread David Faust via Gcc-cvs
https://gcc.gnu.org/g:9b8bc02037eeaf4d6365010bb0533385deb4a90d

commit r14-9928-g9b8bc02037eeaf4d6365010bb0533385deb4a90d
Author: David Faust 
Date:   Thu Apr 11 12:52:36 2024 -0700

btf: fix a possibly misleading asm debug comment

This patch fixes a small error that could occur in the debug comment
when emitting a type reference with btf_asm_type_ref.

While working on a previous patch, I noticed the following in the asm
output for the test btf-bitfields-4.c:

...
.long   0x39# MEMBER 'c' idx=3
.long   0x6 # btm_type: (BTF_KIND_UNKN '')
...
.long   0x34# TYPE 6 BTF_KIND_INT 'char'

The type for member 'c' is correct, but the comment for the member
incorrectly reads "BTF_KIND_UNKN ''".  This was caused by an
incorrect type lookup in btf_asm_type_ref that could happen if the
source file has types which can be represented in CTF but not in BTF.

This patch fixes the issue by changing btf_asm_type_ref to work fully
in the CTF ID space until writing out the final BTF ID.  That ensures
types are correctly identified when writing the asm debug comments,
like the following fixed comment for the above case.

...
.long   0x39# MEMBER 'c' idx=3
.long   0x6 # btm_type: (BTF_KIND_INT 'char')
...

Note that there was no problem with the actual BTF information, the
only error was in the comment.  This patch does not change the output
BTF information, and no tests were affected.

gcc/
* btfout.cc (btf_asm_type_ref): Convert IDs to BTF internally and
fix potentially looking up wrong type for asm debug comment info.
Split into...
(btf_asm_datasec_type_ref): ... This. New.
(btf_asm_datasec_entry): Call it here, instead of btf_asm_type_ref.
(btf_asm_type, btf_asm_array, btf_asm_varent, btf_asm_sou_member)
(btf_asm_func_arg, btf_asm_func_type): Adapt btf_asm_type_ref call.

Diff:
---
 gcc/btfout.cc | 84 +++
 1 file changed, 50 insertions(+), 34 deletions(-)

diff --git a/gcc/btfout.cc b/gcc/btfout.cc
index a1510574a93..07f066a4706 100644
--- a/gcc/btfout.cc
+++ b/gcc/btfout.cc
@@ -738,36 +738,22 @@ btf_dmd_representable_bitfield_p (ctf_container_ref ctfc, 
ctf_dmdef_t *dmd)
 /* Asm'out a reference to another BTF type.  */
 
 static void
-btf_asm_type_ref (const char *prefix, ctf_container_ref ctfc, ctf_id_t ref_id)
+btf_asm_type_ref (const char *prefix, ctf_container_ref ctfc, ctf_id_t ctf_id)
 {
-  if (ref_id == BTF_VOID_TYPEID || ref_id == BTF_INVALID_TYPEID)
+  ctf_id_t btf_id = get_btf_id (ctf_id);
+  if (btf_id == BTF_VOID_TYPEID || btf_id == BTF_INVALID_TYPEID)
 {
   /* There is no explicit void type.
 Also handle any invalid refs that made it this far, just in case.  */
-  dw2_asm_output_data (4, ref_id, "%s: void", prefix);
-}
-  else if (ref_id >= num_types_added + 1
-  && ref_id < num_types_added + num_vars_added + 1)
-{
-  /* Ref to a variable.  Should only appear in DATASEC entries.  */
-  ctf_id_t var_id = btf_relative_var_id (ref_id);
-  ctf_dvdef_ref dvd = ctfc->ctfc_vars_list[var_id];
-  dw2_asm_output_data (4, ref_id, "%s: (BTF_KIND_VAR '%s')",
-  prefix, dvd->dvd_name);
-
-}
-  else if (ref_id >= num_types_added + num_vars_added + 1)
-{
-  /* Ref to a FUNC record.  */
-  size_t func_id = btf_relative_func_id (ref_id);
-  ctf_dtdef_ref ref_type = (*funcs)[func_id];
-  dw2_asm_output_data (4, ref_id, "%s: (BTF_KIND_FUNC '%s')",
-  prefix, get_btf_type_name (ref_type));
+  dw2_asm_output_data (4, btf_id, "%s: void", prefix);
 }
   else
 {
-  /* Ref to a standard type in the types list.  */
-  ctf_dtdef_ref ref_type = ctfc->ctfc_types_list[ref_id];
+  gcc_assert (btf_id <= num_types_added);
+
+  /* Ref to a standard type in the types list.  Note: take care that we
+must index the type list by the original CTF id, not the BTF id.  */
+  ctf_dtdef_ref ref_type = ctfc->ctfc_types_list[ctf_id];
   uint32_t ref_kind
= get_btf_kind (CTF_V2_INFO_KIND (ref_type->dtd_data.ctti_info));
 
@@ -775,12 +761,43 @@ btf_asm_type_ref (const char *prefix, ctf_container_ref 
ctfc, ctf_id_t ref_id)
? btf_kind_name (BTF_KIND_ENUM)
: btf_kind_name (ref_kind);
 
-  dw2_asm_output_data (4, ref_id, "%s: (BTF_KIND_%s '%s')",
+  dw2_asm_output_data (4, btf_id, "%s: (BTF_KIND_%s '%s')",
   prefix, kind_name,
   get_btf_type_name (ref_type));
 }
 }
 
+/* Asm'out a reference to a BTF_KIND_VAR or BTF_KIND_FUNC type.  These type
+   kinds are BTF-specific, and should only be referred to by entries in
+   BTF_KIND_DATASEC records.  */
+

[gcc r14-10131] bpf: avoid issues with CO-RE and -gtoggle

2024-04-25 Thread David Faust via Gcc-cvs
https://gcc.gnu.org/g:f175622d25e4146bb7450430831ec48615e6e4cb

commit r14-10131-gf175622d25e4146bb7450430831ec48615e6e4cb
Author: David Faust 
Date:   Thu Apr 25 09:31:14 2024 -0700

bpf: avoid issues with CO-RE and -gtoggle

Compiling a BPF program with CO-RE relocations (and BTF) while also
passing -gtoggle led to an inconsistent state where CO-RE support was
enabled but BTF would not be generated, and this was not caught by the
existing option parsing.  This led to an ICE when generating the CO-RE
relocation info, since BTF is required for CO-RE.

Update bpf_option_override to avoid this case, and add a few tests for
the interactions of these options.

gcc/
* config/bpf/bpf.cc (bpf_option_override): Improve handling of CO-RE
options to avoid issues with -gtoggle.

gcc/testsuite/
* gcc.target/bpf/core-options-1.c: New test.
* gcc.target/bpf/core-options-2.c: Likewise.
* gcc.target/bpf/core-options-3.c: Likewise.

Diff:
---
 gcc/config/bpf/bpf.cc |  7 +--
 gcc/testsuite/gcc.target/bpf/core-options-1.c | 15 +++
 gcc/testsuite/gcc.target/bpf/core-options-2.c | 14 ++
 gcc/testsuite/gcc.target/bpf/core-options-3.c |  5 +
 4 files changed, 39 insertions(+), 2 deletions(-)

diff --git a/gcc/config/bpf/bpf.cc b/gcc/config/bpf/bpf.cc
index 98fb755bb8b..e6ea211a2c6 100644
--- a/gcc/config/bpf/bpf.cc
+++ b/gcc/config/bpf/bpf.cc
@@ -192,7 +192,8 @@ bpf_option_override (void)
   init_machine_status = bpf_init_machine_status;
 
   /* BPF CO-RE support requires BTF debug info generation.  */
-  if (TARGET_BPF_CORE && !btf_debuginfo_p ())
+  if (TARGET_BPF_CORE
+  && (!btf_debuginfo_p () || (debug_info_level < DINFO_LEVEL_NORMAL)))
 error ("BPF CO-RE requires BTF debugging information, use %<-gbtf%>");
 
   /* BPF applications always generate .BTF.ext.  */
@@ -215,7 +216,9 @@ bpf_option_override (void)
 
   /* -gbtf implies -mcore when using the BPF backend, unless -mno-co-re
  is specified.  */
-  if (btf_debuginfo_p () && !(target_flags_explicit & MASK_BPF_CORE))
+  if (btf_debuginfo_p ()
+  && (debug_info_level >= DINFO_LEVEL_NORMAL)
+  && !(target_flags_explicit & MASK_BPF_CORE))
 target_flags |= MASK_BPF_CORE;
 
   /* Determine available features from ISA setting (-mcpu=).  */
diff --git a/gcc/testsuite/gcc.target/bpf/core-options-1.c 
b/gcc/testsuite/gcc.target/bpf/core-options-1.c
new file mode 100644
index 000..7d8c677f239
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/core-options-1.c
@@ -0,0 +1,15 @@
+/* -gbtf for the BPF target should enable CO-RE support automatically.  */
+/* { dg-do compile } */
+/* { dg-options "-gbtf" } */
+
+struct A {
+  int x;
+  int y;
+  char c;
+};
+
+int
+foo (struct A *a) {
+  int y = __builtin_preserve_access_index (a->y);
+  return y;
+}
diff --git a/gcc/testsuite/gcc.target/bpf/core-options-2.c 
b/gcc/testsuite/gcc.target/bpf/core-options-2.c
new file mode 100644
index 000..8f466258e29
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/core-options-2.c
@@ -0,0 +1,14 @@
+/* { dg-do compile } */
+/* { dg-options "-gbtf -gtoggle" } */
+
+struct A {
+  int x;
+  int y;
+  char c;
+};
+
+int
+foo (struct A *a) {
+  int y = __builtin_preserve_access_index (a->y); /* { dg-error "BPF CO-RE is 
required" } */
+  return y;
+}
diff --git a/gcc/testsuite/gcc.target/bpf/core-options-3.c 
b/gcc/testsuite/gcc.target/bpf/core-options-3.c
new file mode 100644
index 000..ca32a7c4012
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/core-options-3.c
@@ -0,0 +1,5 @@
+/* This combination of options tries to enable CO-RE without BTF, and should
+   produce an error.  */
+/* { dg-do compile } */
+/* { dg-options "-gbtf -gtoggle -mco-re" } */
+/* { dg-excess-errors "BPF CO-RE requires BTF debugging information" } */


[gcc r14-10135] bpf: set PREFERRED_DEBUGGING_TYPE to BTF_DEBUG

2024-04-25 Thread David Faust via Gcc-cvs
https://gcc.gnu.org/g:1604f7cebc49220e47d584615bcd91b1fdc1267f

commit r14-10135-g1604f7cebc49220e47d584615bcd91b1fdc1267f
Author: David Faust 
Date:   Wed Apr 24 15:01:02 2024 -0700

bpf: set PREFERRED_DEBUGGING_TYPE to BTF_DEBUG

BTF is the standard debug info used with BPF programs, so it makes sense
to default to BTF rather than DWARF.

gcc/
* config/bpf/bpf.h (PREFERRED_DEBUGGING_TYPE): Set to BTF_DEBUG.

gcc/testsuite/
* gcc.target/bpf/bpf-debug-options-1.c: New test.
* gcc.target/bpf/bpf-debug-options-2.c: Likewise.
* gcc.target/bpf/bpf-debug-options-3.c: Likewise.
* gcc.target/bpf/core-options-4.c: Likewise.

Diff:
---
 gcc/config/bpf/bpf.h   |  5 +
 gcc/testsuite/gcc.target/bpf/bpf-debug-options-1.c | 17 +
 gcc/testsuite/gcc.target/bpf/bpf-debug-options-2.c | 18 ++
 gcc/testsuite/gcc.target/bpf/bpf-debug-options-3.c | 14 ++
 gcc/testsuite/gcc.target/bpf/core-options-4.c  |  4 
 5 files changed, 58 insertions(+)

diff --git a/gcc/config/bpf/bpf.h b/gcc/config/bpf/bpf.h
index c67e17526bf..e163fbf688d 100644
--- a/gcc/config/bpf/bpf.h
+++ b/gcc/config/bpf/bpf.h
@@ -245,6 +245,11 @@ enum reg_class
 
 / Debugging Info /
 
+/* Use BTF debug info by default.  */
+
+#undef  PREFERRED_DEBUGGING_TYPE
+#define PREFERRED_DEBUGGING_TYPE BTF_DEBUG
+
 /* In eBPF it is not possible to unwind frames. Disable CFA.  */
 
 #define DWARF2_FRAME_INFO 0
diff --git a/gcc/testsuite/gcc.target/bpf/bpf-debug-options-1.c 
b/gcc/testsuite/gcc.target/bpf/bpf-debug-options-1.c
new file mode 100644
index 000..409466c4ead
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/bpf-debug-options-1.c
@@ -0,0 +1,17 @@
+/* Default to BTF debug info.  */
+/* { dg-do compile } */
+/* { dg-options "-g -dA" }*/
+
+struct A {
+  int x;
+  int y;
+};
+
+int
+foo (struct A *a)
+{
+  return a->x;
+}
+
+/* { dg-final { scan-assembler-not "DWARF version" } } */
+/* { dg-final { scan-assembler "btf_version" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/bpf-debug-options-2.c 
b/gcc/testsuite/gcc.target/bpf/bpf-debug-options-2.c
new file mode 100644
index 000..03bde12315b
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/bpf-debug-options-2.c
@@ -0,0 +1,18 @@
+/* -g defaults to BTF, which in turn implies -mco-re.  */
+/* { dg-do compile } */
+/* { dg-options "-g -dA" }*/
+
+struct A {
+  int x;
+  int y;
+};
+
+int
+foo (struct A *a)
+{
+  return __builtin_preserve_access_index (a->x);
+}
+
+/* { dg-final { scan-assembler-not "DWARF version" } } */
+/* { dg-final { scan-assembler "btf_version" } } */
+/* { dg-final { scan-assembler "btfext_version" } } */
diff --git a/gcc/testsuite/gcc.target/bpf/bpf-debug-options-3.c 
b/gcc/testsuite/gcc.target/bpf/bpf-debug-options-3.c
new file mode 100644
index 000..d41790e0928
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/bpf-debug-options-3.c
@@ -0,0 +1,14 @@
+/* Using -g does not incorrectly force CO-RE enabled.  */
+/* { dg-do compile } */
+/* { dg-options "-g -dA -mno-co-re" }*/
+
+struct A {
+  int x;
+  int y;
+};
+
+int
+foo (struct A *a)
+{
+  return __builtin_preserve_access_index (a->x); /* { dg-error "BPF CO-RE is 
required" } */
+}
diff --git a/gcc/testsuite/gcc.target/bpf/core-options-4.c 
b/gcc/testsuite/gcc.target/bpf/core-options-4.c
new file mode 100644
index 000..fde4195da42
--- /dev/null
+++ b/gcc/testsuite/gcc.target/bpf/core-options-4.c
@@ -0,0 +1,4 @@
+/* -g implies BTF, -gtoggle turns it off.  CO-RE should not work.  */
+/* { dg-do compile } */
+/* { dg-options "-g -mco-re -gtoggle" } */
+/* { dg-excess-errors "BPF CO-RE requires BTF debugging information" } */


[gcc r15-2856] btf: Protect BTF_KIND_INFO against invalid kind

2024-08-09 Thread David Faust via Gcc-cvs
https://gcc.gnu.org/g:d0bc1cbf6a8938220f42d8102031fd6f6644e171

commit r15-2856-gd0bc1cbf6a8938220f42d8102031fd6f6644e171
Author: Will Hawkins 
Date:   Mon Jul 29 10:42:48 2024 -0400

btf: Protect BTF_KIND_INFO against invalid kind

If the user provides a kind value that is more than 5 bits, the
BTF_KIND_INFO macro would emit incorrect values for info (by clobbering
values of the kind flag).

Tested on x86_64-redhat-linux.

include/ChangeLog:

* btf.h (BTF_TYPE_INFO): Protect against user providing invalid
kind.

Signed-off-by: Will Hawkins 

Diff:
---
 include/btf.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/btf.h b/include/btf.h
index 3f45ffb0b6bb..0c3e1a1cf518 100644
--- a/include/btf.h
+++ b/include/btf.h
@@ -82,7 +82,7 @@ struct btf_type
   };
 };
 
-/* The folloing macros access the information encoded in btf_type.info.  */
+/* The following macros access the information encoded in btf_type.info.  */
 /* Type kind. See below.  */
 #define BTF_INFO_KIND(info)(((info) >> 24) & 0x1f)
 /* Number of entries of variable length data following certain type kinds.
@@ -95,7 +95,7 @@ struct btf_type
 
 /* Encoding for struct btf_type.info.  */
 #define BTF_TYPE_INFO(kind, kflag, vlen) \
-  kflag) ? 1 : 0 ) << 31) | ((kind) << 24) | ((vlen) & 0x))
+  kflag) ? 1 : 0 ) << 31) | ((kind & 0x1f) << 24) | ((vlen) & 0x))
 
 #define BTF_KIND_UNKN  0   /* Unknown or invalid.  */
 #define BTF_KIND_INT   1   /* Integer.  */


[gcc r15-5025] btf: check hash maps are non-null before emptying

2024-11-07 Thread David Faust via Gcc-cvs
https://gcc.gnu.org/g:6571e8f863736b7705f59c9ab0f17b7c4fdbcf92

commit r15-5025-g6571e8f863736b7705f59c9ab0f17b7c4fdbcf92
Author: David Faust 
Date:   Thu Nov 7 09:19:51 2024 -0800

btf: check hash maps are non-null before emptying

These maps will always be non-null in btf_finalize under normal
circumstances, but be safe and verify that before trying to empty them.

gcc/
* btfout.cc (btf_finalize): Check that hash maps are non-null before
emptying them.

Diff:
---
 gcc/btfout.cc | 14 ++
 1 file changed, 10 insertions(+), 4 deletions(-)

diff --git a/gcc/btfout.cc b/gcc/btfout.cc
index 083ca48d6279..4a6b5453e08e 100644
--- a/gcc/btfout.cc
+++ b/gcc/btfout.cc
@@ -1661,13 +1661,19 @@ btf_finalize (void)
   datasecs.release ();
 
   funcs = NULL;
-  func_map->empty ();
-  func_map = NULL;
+  if (func_map)
+{
+  func_map->empty ();
+  func_map = NULL;
+}
 
   if (debug_prune_btf)
 {
-  btf_used_types->empty ();
-  btf_used_types = NULL;
+  if (btf_used_types)
+   {
+ btf_used_types->empty ();
+ btf_used_types = NULL;
+   }
 
   fixups.release ();
   forwards = NULL;


[gcc r15-5026] bpf: avoid possible null deref in btf_ext_output [PR target/117447]

2024-11-07 Thread David Faust via Gcc-cvs
https://gcc.gnu.org/g:0e1382034246a594f1da8dbaee97c4a06743f31a

commit r15-5026-g0e1382034246a594f1da8dbaee97c4a06743f31a
Author: David Faust 
Date:   Thu Nov 7 09:27:07 2024 -0800

bpf: avoid possible null deref in btf_ext_output [PR target/117447]

The BPF-specific .BTF.ext section is always generated for BPF programs
if -gbtf is specified, and generating it requires BTF information and
assumes that the BTF info has already been generated.

Compiling non-C languages to BPF is not supported, nor is generating
CTF/BTF for non-C.  But, compiling another language like C++ to BPF
with -gbtf specified meant that we would try to generate the .BTF.ext
section anyway, and then ICE because no BTF information was available.

Add a check to bail out of btf_ext_output if the TU CTFC does not exist,
meaning no BTF info is available.

gcc/
PR target/117447
* config/bpf/btfext-out.cc (btf_ext_output): Bail if TU CTFC is 
null.

Diff:
---
 gcc/config/bpf/btfext-out.cc | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/gcc/config/bpf/btfext-out.cc b/gcc/config/bpf/btfext-out.cc
index ca6241aa52ee..760b2b59ff6a 100644
--- a/gcc/config/bpf/btfext-out.cc
+++ b/gcc/config/bpf/btfext-out.cc
@@ -611,6 +611,9 @@ btf_ext_init (void)
 void
 btf_ext_output (void)
 {
+  if (!ctf_get_tu_ctfc ())
+return;
+
   output_btfext_header ();
   output_btfext_func_info (btf_ext);
   if (TARGET_BPF_CORE)