aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ctfc.cc62
-rw-r--r--gcc/ctfc.h6
-rw-r--r--gcc/ctfout.cc24
-rw-r--r--gcc/dwarf2ctf.cc18
4 files changed, 98 insertions, 12 deletions
diff --git a/gcc/ctfc.cc b/gcc/ctfc.cc
index 6fe44d2..f24e7bf 100644
--- a/gcc/ctfc.cc
+++ b/gcc/ctfc.cc
@@ -179,6 +179,40 @@ ctf_dvd_lookup (const ctf_container_ref ctfc, dw_die_ref die)
return NULL;
}
+/* Insert a dummy CTF variable into the list of variables to be ignored. */
+
+static void
+ctf_dvd_ignore_insert (ctf_container_ref ctfc, ctf_dvdef_ref dvd)
+{
+ bool existed = false;
+ ctf_dvdef_ref entry = dvd;
+
+ ctf_dvdef_ref * item = ctfc->ctfc_ignore_vars->find_slot (entry, INSERT);
+ if (*item == NULL)
+ *item = dvd;
+ else
+ existed = true;
+ /* Duplicate variable records not expected to be inserted. */
+ gcc_assert (!existed);
+}
+
+/* Lookup the dummy CTF variable given the DWARF die for the non-defining
+ decl to be ignored. */
+
+bool
+ctf_dvd_ignore_lookup (const ctf_container_ref ctfc, dw_die_ref die)
+{
+ ctf_dvdef_t entry;
+ entry.dvd_key = die;
+
+ ctf_dvdef_ref * slot = ctfc->ctfc_ignore_vars->find_slot (&entry, NO_INSERT);
+
+ if (slot)
+ return true;
+
+ return false;
+}
+
/* Append member definition to the list. Member list is a singly-linked list
with list start pointing to the head. */
@@ -666,9 +700,10 @@ ctf_add_member_offset (ctf_container_ref ctfc, dw_die_ref sou,
int
ctf_add_variable (ctf_container_ref ctfc, const char * name, ctf_id_t ref,
- dw_die_ref die, unsigned int external_vis)
+ dw_die_ref die, unsigned int external_vis,
+ dw_die_ref die_var_decl)
{
- ctf_dvdef_ref dvd;
+ ctf_dvdef_ref dvd, dvd_ignore;
gcc_assert (name);
@@ -680,6 +715,24 @@ ctf_add_variable (ctf_container_ref ctfc, const char * name, ctf_id_t ref,
dvd->dvd_name = ctf_add_string (ctfc, name, &(dvd->dvd_name_offset));
dvd->dvd_visibility = external_vis;
dvd->dvd_type = ref;
+
+ /* If DW_AT_specification attribute exists, keep track of it as this is
+ the non-defining declaration corresponding to the variable. We will
+ skip emitting CTF variable for such incomplete, non-defining
+ declarations.
+ There could be some non-defining declarations, however, for which a
+ defining declaration does not show up in the same CU. For such
+ cases, the compiler continues to emit CTF variable record as
+ usual. */
+ if (die_var_decl)
+ {
+ dvd_ignore = ggc_cleared_alloc<ctf_dvdef_t> ();
+ dvd_ignore->dvd_key = die_var_decl;
+ /* It's alright to leave other fields as zero. No valid CTF
+ variable will be added for these DW_TAG_variable DIEs. */
+ ctf_dvd_ignore_insert (ctfc, dvd_ignore);
+ }
+
ctf_dvd_insert (ctfc, dvd);
if (strcmp (name, ""))
@@ -900,6 +953,8 @@ new_ctf_container (void)
= hash_table<ctfc_dtd_hasher>::create_ggc (100);
tu_ctfc->ctfc_vars
= hash_table<ctfc_dvd_hasher>::create_ggc (100);
+ tu_ctfc->ctfc_ignore_vars
+ = hash_table<ctfc_dvd_hasher>::create_ggc (10);
return tu_ctfc;
}
@@ -952,6 +1007,9 @@ ctfc_delete_container (ctf_container_ref ctfc)
ctfc->ctfc_vars->empty ();
ctfc->ctfc_types = NULL;
+ ctfc->ctfc_ignore_vars->empty ();
+ ctfc->ctfc_ignore_vars = NULL;
+
ctfc_delete_strtab (&ctfc->ctfc_strtable);
ctfc_delete_strtab (&ctfc->ctfc_aux_strtable);
if (ctfc->ctfc_vars_list)
diff --git a/gcc/ctfc.h b/gcc/ctfc.h
index 4ce756c..001e544 100644
--- a/gcc/ctfc.h
+++ b/gcc/ctfc.h
@@ -274,6 +274,8 @@ typedef struct GTY (()) ctf_container
hash_table <ctfc_dtd_hasher> * GTY (()) ctfc_types;
/* CTF variables. */
hash_table <ctfc_dvd_hasher> * GTY (()) ctfc_vars;
+ /* CTF variables to be ignored. */
+ hash_table <ctfc_dvd_hasher> * GTY (()) ctfc_ignore_vars;
/* CTF string table. */
ctf_strtable_t ctfc_strtable;
@@ -394,6 +396,8 @@ extern ctf_dtdef_ref ctf_dtd_lookup (const ctf_container_ref ctfc,
dw_die_ref die);
extern ctf_dvdef_ref ctf_dvd_lookup (const ctf_container_ref ctfc,
dw_die_ref die);
+extern bool ctf_dvd_ignore_lookup (const ctf_container_ref ctfc,
+ dw_die_ref die);
extern const char * ctf_add_string (ctf_container_ref, const char *,
uint32_t *, int);
@@ -430,7 +434,7 @@ extern int ctf_add_member_offset (ctf_container_ref, dw_die_ref, const char *,
extern int ctf_add_function_arg (ctf_container_ref, dw_die_ref,
const char *, ctf_id_t);
extern int ctf_add_variable (ctf_container_ref, const char *, ctf_id_t,
- dw_die_ref, unsigned int);
+ dw_die_ref, unsigned int, dw_die_ref);
extern ctf_id_t ctf_lookup_tree_type (ctf_container_ref, const tree);
extern ctf_id_t get_btf_id (ctf_id_t);
diff --git a/gcc/ctfout.cc b/gcc/ctfout.cc
index 28a873b..3cf89b9 100644
--- a/gcc/ctfout.cc
+++ b/gcc/ctfout.cc
@@ -212,6 +212,13 @@ ctf_dvd_preprocess_cb (ctf_dvdef_ref * slot, void * arg)
ctf_dvdef_ref var = (ctf_dvdef_ref) *slot;
ctf_container_ref arg_ctfc = dvd_arg->dvd_arg_ctfc;
+ /* If the CTF variable corresponds to an extern variable declaration with
+ a defining declaration later on, skip it. Only CTF variable
+ corresponding to the defining declaration for the extern variable is
+ desirable. */
+ if (ctf_dvd_ignore_lookup (arg_ctfc, var->dvd_key))
+ return 1;
+
ctf_preprocess_var (arg_ctfc, var);
/* Keep track of global objts. */
@@ -276,16 +283,16 @@ static void
ctf_preprocess (ctf_container_ref ctfc)
{
size_t num_ctf_types = ctfc->ctfc_types->elements ();
+ size_t num_ctf_vars = ctfc_get_num_ctf_vars (ctfc);
/* Initialize an array to keep track of the CTF variables at global
- scope. */
- size_t num_global_objts = ctfc->ctfc_num_global_objts;
+ scope. At this time, size it conservatively. */
+ size_t num_global_objts = num_ctf_vars;
if (num_global_objts)
{
ctfc->ctfc_gobjts_list = ggc_vec_alloc<ctf_dvdef_t*>(num_global_objts);
}
- size_t num_ctf_vars = ctfc_get_num_ctf_vars (ctfc);
if (num_ctf_vars)
{
ctf_dvd_preprocess_arg_t dvd_arg;
@@ -299,8 +306,11 @@ ctf_preprocess (ctf_container_ref ctfc)
list for sorting. */
ctfc->ctfc_vars->traverse<void *, ctf_dvd_preprocess_cb> (&dvd_arg);
/* Sort the list. */
- qsort (ctfc->ctfc_vars_list, num_ctf_vars, sizeof (ctf_dvdef_ref),
- ctf_varent_compare);
+ qsort (ctfc->ctfc_vars_list, ctfc->ctfc_vars_list_count,
+ sizeof (ctf_dvdef_ref), ctf_varent_compare);
+ /* Update the actual number of the generated CTF variables at global
+ scope. */
+ ctfc->ctfc_num_global_objts = dvd_arg.dvd_global_obj_idx;
}
/* Initialize an array to keep track of the CTF functions types for global
@@ -476,7 +486,7 @@ output_ctf_header (ctf_container_ref ctfc)
/* Vars appear after function index. */
varoff = funcidxoff + ctfc->ctfc_num_global_funcs * sizeof (uint32_t);
/* CTF types appear after vars. */
- typeoff = varoff + ctfc_get_num_ctf_vars (ctfc) * sizeof (ctf_varent_t);
+ typeoff = varoff + (ctfc->ctfc_vars_list_count) * sizeof (ctf_varent_t);
/* The total number of bytes for CTF types is the sum of the number of
times struct ctf_type_t, struct ctf_stype_t are written, plus the
amount of variable length data after each one of these. */
@@ -595,7 +605,7 @@ static void
output_ctf_vars (ctf_container_ref ctfc)
{
size_t i;
- size_t num_ctf_vars = ctfc_get_num_ctf_vars (ctfc);
+ unsigned int num_ctf_vars = ctfc->ctfc_vars_list_count;
if (num_ctf_vars)
{
/* Iterate over the list of sorted vars and output the asm. */
diff --git a/gcc/dwarf2ctf.cc b/gcc/dwarf2ctf.cc
index 747b2f6..a6329ab 100644
--- a/gcc/dwarf2ctf.cc
+++ b/gcc/dwarf2ctf.cc
@@ -808,12 +808,26 @@ gen_ctf_variable (ctf_container_ref ctfc, dw_die_ref die)
if (ctf_dvd_lookup (ctfc, die))
return;
+ /* Do not generate CTF variable records for non-defining incomplete
+ declarations. Such declarations can be known via the DWARF
+ DW_AT_specification attribute. */
+ if (ctf_dvd_ignore_lookup (ctfc, die))
+ return;
+
+ /* The value of the DW_AT_specification attribute, if present, is a
+ reference to the debugging information entry representing the
+ non-defining declaration. */
+ dw_die_ref decl = get_AT_ref (die, DW_AT_specification);
+
/* Add the type of the variable. */
var_type_id = gen_ctf_type (ctfc, var_type);
/* Generate the new CTF variable and update global counter. */
- (void) ctf_add_variable (ctfc, var_name, var_type_id, die, external_vis);
- ctfc->ctfc_num_global_objts += 1;
+ (void) ctf_add_variable (ctfc, var_name, var_type_id, die, external_vis,
+ decl);
+ /* Skip updating the number of global objects at this time. This is updated
+ later after pre-processing as some CTF variable records although
+ generated now, will not be emitted later. [PR105089]. */
}
/* Add a CTF function record for the given input DWARF DIE. */