libctf, dedup: drop unnecessary arg from ctf_dedup()

The PARENTS arg is carefully passed down through all the layers of hash
functions and then never used for anything.  (In the distant past it was
used for cycle detection, but the algorithm eventually committed doesn't
need to do cycle detection...)

The PARENTS arg is still used by ctf_dedup_emit(), but even there we can
loosen the requirements and state that you can just leave entries
corresponding to dicts with no parents at zero (which will be useful
in an upcoming commit).

libctf/
	* ctf-dedup.c (ctf_dedup_hash_type): Drop PARENTS arg.
	(ctf_dedup_rhash_type): Likewise.
	(ctf_dedup): Likewise.
	(ctf_dedup_emit_struct_members): Mention what you can do to
        PARENTS entries for parent dicts.
	* ctf-impl.h (ctf_dedup): Adjust accordingly.
	* ctf-link.c (ctf_link_deduplicating_per_cu): Likewise.
	(ctf_link_deduplicating): Likewise.
This commit is contained in:
Nick Alcock
2024-07-09 15:30:39 +01:00
parent cc7069a8c8
commit 5d64742afa
3 changed files with 30 additions and 36 deletions

View File

@@ -485,9 +485,8 @@ ctf_dedup_sha1_add (ctf_sha1_t *sha1, const void *buf, size_t len,
static const char * static const char *
ctf_dedup_hash_type (ctf_dict_t *fp, ctf_dict_t *input, ctf_dedup_hash_type (ctf_dict_t *fp, ctf_dict_t *input,
ctf_dict_t **inputs, uint32_t *parents, ctf_dict_t **inputs, int input_num,
int input_num, ctf_id_t type, int flags, ctf_id_t type, int flags, unsigned long depth,
unsigned long depth,
int (*populate_fun) (ctf_dict_t *fp, int (*populate_fun) (ctf_dict_t *fp,
ctf_dict_t *input, ctf_dict_t *input,
ctf_dict_t **inputs, ctf_dict_t **inputs,
@@ -552,8 +551,8 @@ ctf_dedup_record_origin (ctf_dict_t *fp, int input_num, const char *decorated,
static const char * static const char *
ctf_dedup_rhash_type (ctf_dict_t *fp, ctf_dict_t *input, ctf_dict_t **inputs, ctf_dedup_rhash_type (ctf_dict_t *fp, ctf_dict_t *input, ctf_dict_t **inputs,
uint32_t *parents, int input_num, ctf_id_t type, int input_num, ctf_id_t type, void *type_id,
void *type_id, const ctf_type_t *tp, const char *name, const ctf_type_t *tp, const char *name,
const char *decorated, int kind, int flags, const char *decorated, int kind, int flags,
unsigned long depth, unsigned long depth,
int (*populate_fun) (ctf_dict_t *fp, int (*populate_fun) (ctf_dict_t *fp,
@@ -711,9 +710,8 @@ ctf_dedup_rhash_type (ctf_dict_t *fp, ctf_dict_t *input, ctf_dict_t **inputs,
case CTF_K_POINTER: case CTF_K_POINTER:
/* Hash the referenced type, if not already hashed, and mix it in. */ /* Hash the referenced type, if not already hashed, and mix it in. */
child_type = ctf_type_reference (input, type); child_type = ctf_type_reference (input, type);
if ((hval = ctf_dedup_hash_type (fp, input, inputs, parents, input_num, if ((hval = ctf_dedup_hash_type (fp, input, inputs, input_num, child_type,
child_type, flags, depth, flags, depth, populate_fun)) == NULL)
populate_fun)) == NULL)
{ {
whaterr = N_("error doing referenced type hashing"); whaterr = N_("error doing referenced type hashing");
goto err; goto err;
@@ -740,7 +738,7 @@ ctf_dedup_rhash_type (ctf_dict_t *fp, ctf_dict_t *input, ctf_dict_t **inputs,
ctf_get_ctt_size (input, tp, &size, &increment); ctf_get_ctt_size (input, tp, &size, &increment);
ctf_dedup_sha1_add (&hash, &size, sizeof (ssize_t), "size", depth); ctf_dedup_sha1_add (&hash, &size, sizeof (ssize_t), "size", depth);
if ((hval = ctf_dedup_hash_type (fp, input, inputs, parents, input_num, if ((hval = ctf_dedup_hash_type (fp, input, inputs, input_num,
child_type, flags, depth, child_type, flags, depth,
populate_fun)) == NULL) populate_fun)) == NULL)
{ {
@@ -773,7 +771,7 @@ ctf_dedup_rhash_type (ctf_dict_t *fp, ctf_dict_t *input, ctf_dict_t **inputs,
goto input_err; goto input_err;
} }
if ((hval = ctf_dedup_hash_type (fp, input, inputs, parents, input_num, if ((hval = ctf_dedup_hash_type (fp, input, inputs, input_num,
ar.ctr_contents, flags, depth, ar.ctr_contents, flags, depth,
populate_fun)) == NULL) populate_fun)) == NULL)
{ {
@@ -784,7 +782,7 @@ ctf_dedup_rhash_type (ctf_dict_t *fp, ctf_dict_t *input, ctf_dict_t **inputs,
depth); depth);
ADD_CITER (citers, hval); ADD_CITER (citers, hval);
if ((hval = ctf_dedup_hash_type (fp, input, inputs, parents, input_num, if ((hval = ctf_dedup_hash_type (fp, input, inputs, input_num,
ar.ctr_index, flags, depth, ar.ctr_index, flags, depth,
populate_fun)) == NULL) populate_fun)) == NULL)
{ {
@@ -811,7 +809,7 @@ ctf_dedup_rhash_type (ctf_dict_t *fp, ctf_dict_t *input, ctf_dict_t **inputs,
goto input_err; goto input_err;
} }
if ((hval = ctf_dedup_hash_type (fp, input, inputs, parents, input_num, if ((hval = ctf_dedup_hash_type (fp, input, inputs, input_num,
fi.ctc_return, flags, depth, fi.ctc_return, flags, depth,
populate_fun)) == NULL) populate_fun)) == NULL)
{ {
@@ -841,8 +839,8 @@ ctf_dedup_rhash_type (ctf_dict_t *fp, ctf_dict_t *input, ctf_dict_t **inputs,
} }
for (j = 0; j < fi.ctc_argc; j++) for (j = 0; j < fi.ctc_argc; j++)
{ {
if ((hval = ctf_dedup_hash_type (fp, input, inputs, parents, if ((hval = ctf_dedup_hash_type (fp, input, inputs, input_num,
input_num, args[j], flags, depth, args[j], flags, depth,
populate_fun)) == NULL) populate_fun)) == NULL)
{ {
free (args); free (args);
@@ -900,8 +898,8 @@ ctf_dedup_rhash_type (ctf_dict_t *fp, ctf_dict_t *input, ctf_dict_t **inputs,
#ifdef ENABLE_LIBCTF_HASH_DEBUGGING #ifdef ENABLE_LIBCTF_HASH_DEBUGGING
ctf_dprintf ("%lu: Traversing to member %s\n", depth, mname); ctf_dprintf ("%lu: Traversing to member %s\n", depth, mname);
#endif #endif
if ((hval = ctf_dedup_hash_type (fp, input, inputs, parents, if ((hval = ctf_dedup_hash_type (fp, input, inputs, input_num,
input_num, membtype, flags, depth, membtype, flags, depth,
populate_fun)) == NULL) populate_fun)) == NULL)
{ {
whaterr = N_("error doing struct/union member type hashing"); whaterr = N_("error doing struct/union member type hashing");
@@ -990,8 +988,7 @@ ctf_dedup_rhash_type (ctf_dict_t *fp, ctf_dict_t *input, ctf_dict_t **inputs,
/* Hash a TYPE in the INPUT: FP is the eventual output, where the ctf_dedup /* Hash a TYPE in the INPUT: FP is the eventual output, where the ctf_dedup
state is stored. INPUT_NUM is the number of this input in the set of inputs. state is stored. INPUT_NUM is the number of this input in the set of inputs.
Record its hash in FP's cd_type_hashes once it is known. PARENTS is Record its hash in FP's cd_type_hashes once it is known.
described in the comment above ctf_dedup.
(The flags argument currently accepts only the flag (The flags argument currently accepts only the flag
CTF_DEDUP_HASH_INTERNAL_CHILD, an implementation detail used to prevent CTF_DEDUP_HASH_INTERNAL_CHILD, an implementation detail used to prevent
@@ -1011,9 +1008,8 @@ ctf_dedup_rhash_type (ctf_dict_t *fp, ctf_dict_t *input, ctf_dict_t **inputs,
static const char * static const char *
ctf_dedup_hash_type (ctf_dict_t *fp, ctf_dict_t *input, ctf_dedup_hash_type (ctf_dict_t *fp, ctf_dict_t *input,
ctf_dict_t **inputs, uint32_t *parents, ctf_dict_t **inputs, int input_num, ctf_id_t type,
int input_num, ctf_id_t type, int flags, int flags, unsigned long depth,
unsigned long depth,
int (*populate_fun) (ctf_dict_t *fp, int (*populate_fun) (ctf_dict_t *fp,
ctf_dict_t *input, ctf_dict_t *input,
ctf_dict_t **inputs, ctf_dict_t **inputs,
@@ -1103,7 +1099,7 @@ ctf_dedup_hash_type (ctf_dict_t *fp, ctf_dict_t *input,
Hash this type, and call ourselves recursively. (The hashing part is Hash this type, and call ourselves recursively. (The hashing part is
optional, and is disabled if overidden_hval is set.) */ optional, and is disabled if overidden_hval is set.) */
if ((hval = ctf_dedup_rhash_type (fp, input, inputs, parents, input_num, if ((hval = ctf_dedup_rhash_type (fp, input, inputs, input_num,
type, type_id, tp, name, decorated, type, type_id, tp, name, decorated,
kind, flags, depth, populate_fun)) == NULL) kind, flags, depth, populate_fun)) == NULL)
return NULL; /* errno is set for us. */ return NULL; /* errno is set for us. */
@@ -1911,13 +1907,11 @@ ctf_dedup_conflictify_unshared (ctf_dict_t *output, ctf_dict_t **inputs)
return ctf_set_errno (output, err); return ctf_set_errno (output, err);
} }
/* The core deduplicator. Populate cd_output_mapping in the output ctf_dedup /* The core deduplicator. Populate cd_output_mapping in the output ctf_dedup with a
with a mapping of all types that belong in this dictionary and where they mapping of all types that belong in this dictionary and where they come from, and
come from, and cd_conflicting_types with an indication of whether each type cd_conflicting_types with an indication of whether each type is conflicted or not.
is conflicted or not. OUTPUT is the top-level output: INPUTS is the array of OUTPUT is the top-level output: INPUTS is the array of input dicts; NINPUTS is the
input dicts; NINPUTS is the size of that array; PARENTS is an NINPUTS-element size of that array.
array with each element corresponding to a input which is a child dict set to
the number in the INPUTS array of that input's parent.
If CU_MAPPED is set, this is a first pass for a link with a non-empty CU If CU_MAPPED is set, this is a first pass for a link with a non-empty CU
mapping: only one output will result. mapping: only one output will result.
@@ -1927,7 +1921,7 @@ ctf_dedup_conflictify_unshared (ctf_dict_t *output, ctf_dict_t **inputs)
int int
ctf_dedup (ctf_dict_t *output, ctf_dict_t **inputs, uint32_t ninputs, ctf_dedup (ctf_dict_t *output, ctf_dict_t **inputs, uint32_t ninputs,
uint32_t *parents, int cu_mapped) int cu_mapped)
{ {
ctf_dedup_t *d = &output->ctf_dedup; ctf_dedup_t *d = &output->ctf_dedup;
size_t i; size_t i;
@@ -1973,7 +1967,7 @@ ctf_dedup (ctf_dict_t *output, ctf_dict_t **inputs, uint32_t ninputs,
while ((id = ctf_type_next (inputs[i], &it, NULL, 1)) != CTF_ERR) while ((id = ctf_type_next (inputs[i], &it, NULL, 1)) != CTF_ERR)
{ {
if (ctf_dedup_hash_type (output, inputs[i], inputs, if (ctf_dedup_hash_type (output, inputs[i], inputs,
parents, i, id, 0, 0, i, id, 0, 0,
ctf_dedup_populate_mappings) == NULL) ctf_dedup_populate_mappings) == NULL)
goto err; /* errno is set for us. */ goto err; /* errno is set for us. */
} }
@@ -3085,7 +3079,7 @@ ctf_dedup_emit_struct_members (ctf_dict_t *output, ctf_dict_t **inputs,
OUTPUT, on which the ctf_dedup function must have already been called. The OUTPUT, on which the ctf_dedup function must have already been called. The
PARENTS array contains the INPUTS index of the parent dict for every child PARENTS array contains the INPUTS index of the parent dict for every child
dict at the corresponding index in the INPUTS (for non-child dicts, the value dict at the corresponding index in the INPUTS (for non-child dicts, the value
is undefined). is undefined and can just be left at zero).
Return an array of fps with content emitted into them (starting with OUTPUT, Return an array of fps with content emitted into them (starting with OUTPUT,
which is the parent of all others, then all the newly-generated outputs). which is the parent of all others, then all the newly-generated outputs).

View File

@@ -715,11 +715,11 @@ extern int ctf_add_funcobjt_sym_forced (ctf_dict_t *, int is_function,
extern int ctf_dedup_atoms_init (ctf_dict_t *); extern int ctf_dedup_atoms_init (ctf_dict_t *);
extern int ctf_dedup (ctf_dict_t *, ctf_dict_t **, uint32_t ninputs, extern int ctf_dedup (ctf_dict_t *, ctf_dict_t **, uint32_t ninputs,
uint32_t *parents, int cu_mapped); int cu_mapped);
extern void ctf_dedup_fini (ctf_dict_t *, ctf_dict_t **, uint32_t);
extern ctf_dict_t **ctf_dedup_emit (ctf_dict_t *, ctf_dict_t **, extern ctf_dict_t **ctf_dedup_emit (ctf_dict_t *, ctf_dict_t **,
uint32_t ninputs, uint32_t *parents, uint32_t ninputs, uint32_t *parents,
uint32_t *noutputs, int cu_mapped); uint32_t *noutputs, int cu_mapped);
extern void ctf_dedup_fini (ctf_dict_t *, ctf_dict_t **, uint32_t);
extern ctf_id_t ctf_dedup_type_mapping (ctf_dict_t *fp, ctf_dict_t *src_fp, extern ctf_id_t ctf_dedup_type_mapping (ctf_dict_t *fp, ctf_dict_t *src_fp,
ctf_id_t src_type); ctf_id_t src_type);

View File

@@ -1242,7 +1242,7 @@ ctf_link_deduplicating_per_cu (ctf_dict_t *fp)
dictionary. */ dictionary. */
ctf_cuname_set (out, out_name); ctf_cuname_set (out, out_name);
if (ctf_dedup (out, inputs, ninputs, parents, 1) < 0) if (ctf_dedup (out, inputs, ninputs, 1) < 0)
{ {
ctf_set_errno (fp, ctf_errno (out)); ctf_set_errno (fp, ctf_errno (out));
ctf_err_warn (fp, 0, 0, _("CU-mapped deduplication failed for %s"), ctf_err_warn (fp, 0, 0, _("CU-mapped deduplication failed for %s"),
@@ -1401,7 +1401,7 @@ ctf_link_deduplicating (ctf_dict_t *fp)
if (ninputs == 1 && ctf_cuname (inputs[0]) != NULL) if (ninputs == 1 && ctf_cuname (inputs[0]) != NULL)
ctf_cuname_set (fp, ctf_cuname (inputs[0])); ctf_cuname_set (fp, ctf_cuname (inputs[0]));
if (ctf_dedup (fp, inputs, ninputs, parents, 0) < 0) if (ctf_dedup (fp, inputs, ninputs, 0) < 0)
{ {
ctf_err_warn (fp, 0, 0, _("deduplication failed for %s"), ctf_err_warn (fp, 0, 0, _("deduplication failed for %s"),
ctf_link_input_name (fp)); ctf_link_input_name (fp));