[Bug default/26646] unexpected declaration-only types
dodji at seketeli dot org
sourceware-bugzilla@sourceware.org
Wed Mar 2 13:34:14 GMT 2022
https://sourceware.org/bugzilla/show_bug.cgi?id=26646
--- Comment #31 from dodji at seketeli dot org ---
Dodji Seketeli via Libabigail <libabigail@sourceware.org> a écrit:
[...]
> This addresses https://sourceware.org/bugzilla/show_bug.cgi?id=26646#c21.
>
> * src/abg-dwarf-reader.cc (compare_dies): Do not propagate
> canonical type when aggregate redundancy is detected.
>
[...]
gprocida at google dot com via Libabigail <libabigail@sourceware.org> a
écrit:
[...]
> I've thought a little bit more about this one.
>
> The current check is "local", recursion prevention at *this* DIE
> prevents it from being canonicalised, but it could still depend on
> child DIEs that are actually also parent DIEs and whose processing has
> not yet been completed.
You are right. The current state is an improvement, but it's not
"complete". Some DIEs might still wrongly considered as being
equivalent just because they depend on a "recursive DIE" that was
detected as such. The canonical DIE propagation might have happened
during the window of time where the recursive DIE was comparing equal to
its counterpart.
This is addressed in the IR type canonicalization algorithm in
abg-ir.cc.
To learn more about this, look for
/// @defgroup OnTheFlyCanonicalization On-the-fly Canonicalization
and that comment.
The implementation is scattered in the functions
return_comparison_result, maybe_propagate_canonical_type and in the
macro RETURN_TRUE_IF_COMPARISON_CYCLE_DETECTED.
More on this below ...
> Would it be safer (more precise) to inhibit on-the-fly
> canonicalisation whenever the set (stack) of aggregates being compared
> is non-empty?
Right, that is the obvious thing to do, as I thought. But then the
problem I encountered, when doing this for IR types, was that things
were too slow. Really really slow. In the time window where the
canonical type DIE is inhibited, the amount of (quadratic) structural
DIE comparisons goes through the roof. That is why I came up with the
canonical type propagation in the first place.
So, the other (harder) approach I've taken is to not disable the
on-the-fly canonicalization when the stack of aggregates being compared
is non-empty, but rather, keep track of the types which are resolved as
being equivalent, but that depend on recursive aggregate that were
detected as such.
I call these types "dependent types". Let's consider one such dependent
type D. D's canonical type is the result of canonical propagation that
happened as the recursive type (that D depends on) was on the stack of
aggregates being compared. D is labelled as having a "non-confirmed"
canonical type. If the recursive type it depends on is later considered
not being equivalent to its counterpart, then the non-confirmed
canonical of D is going to be "cancelled" and then D is going to be
considered as being non canonicalized.
This is done for D and all the types that depends on it.
By doing this, the number of non canonicalized types is reduced to its
absolute minimum and so comparisons are reasonably fast, even for an
applications like the Kernel or Gimp. Libraries usually have smaller
type graphs so we don't usually see the speed issue there. Unless it's
llvm.so or libwebkit.so ;-)
So, I wasn't going to get into doing this for DIEs right away because it
takes a lot of time doing careful coding/debugging/profiling cycles.
But I definitely think we'll need to do this to have perfectly precise
canonicalizer. My point was to get this in as it's an improvement
already and then work on the subsequent patch with a cooler head.
Does that make any sense?
Thanks.
--
You are receiving this mail because:
You are on the CC list for the bug.
More information about the Libabigail
mailing list