dwarf-reader: Speed-up decl-only resolution

After the IR is constructed, decl-only classes and enums are resolved
to their definition, for cases where the link between the declaration
and the definition is not obviously stated in the DWARF
representation.

During that resolution, it often happens that types are compared.  As
that comparison happens before type canonicalization, the comparison
is structural.  So it takes time and it can take forever.

As pre-canonicalization type comparison happens between artifacts that
are from the same binary, we can consider that two types of the same
name and kind having the same source location are equivalent.

This optimization speeds up things A LOT.  So much so that
self-comparing the usr/libexec/gcc/s390x-redhat-linux/12/gnat1 binary
(from the gcc-gnat package) now takes less than 4 minutes, down from
more than one hour!

	* src/abg-dwarf-reader.cc
	(reader::compare_before_canonicalisation): If the two types being
	compared are of the same kind and name, and are declared at the
	same source location, then they ought to be equivalent.
	* tests/data/test-annotate/test14-pr18893.so.abi: Adjust.
	* tests/data/test-read-dwarf/test14-pr18893.so.abi: Likewise.
	* tests/data/test-diff-pkg/spice-server-0.12.4-19.el7.x86_64-0.12.8-1.el7.x86_64-report-2.txt:
	Likewise.

Signed-off-by: Dodji Seketeli <dodji@redhat.com>
This commit is contained in:
Dodji Seketeli 2024-08-14 17:50:44 +02:00
parent a75424b6e5
commit 6381bbebe6
4 changed files with 1681 additions and 4382 deletions

View File

@ -4102,6 +4102,9 @@ public:
/// Compare two ABI artifacts in a context which canonicalization
/// has not be done yet.
///
/// Please note that this should only be called on IR nodes that
/// belong to the same binary.
///
/// @param l the left-hand-side operand of the comparison
///
/// @param r the right-hand-side operand of the comparison.
@ -4117,6 +4120,37 @@ public:
const environment& e = l->get_environment();
ABG_ASSERT(!e.canonicalization_is_done());
if (is_decl(l) && is_decl(r)
&& l->kind() == r->kind()
&& ((l->get_corpus() && r->get_corpus()
&& (l->get_corpus() == r->get_corpus()))
||(l->get_translation_unit()
&& r->get_translation_unit()
&& l->get_translation_unit() == r->get_translation_unit())))
{
// Fast path optimization. If the two types are declared at
// the same location (in the same binary) then it very likely
// means the two types are equal.
//
// We really need every bit of optimization here because
// otherwise, comparing types before canonicalization can take
// forever.*
decl_base *ld = is_decl(l.get());
decl_base *rd = is_decl(r.get());
ABG_ASSERT(ld && rd);
if (ld->get_qualified_name() != rd->get_qualified_name())
return false;
location ll = ld->get_location(), rl = rd->get_location();
if (ll && rl)
{
string l1 = ll.expand();
string l2 = rl.expand();
if (l1 == l2)
return true;
}
}
e.priv_->allow_type_comparison_results_caching(true);
bool s0 = e.decl_only_class_equals_definition();
e.decl_only_class_equals_definition(true);

File diff suppressed because it is too large Load Diff

View File

@ -287,7 +287,7 @@
'unsigned int tlsext_hb_pending', at offset 5408 (in bits) at ssl.h:1302:1
'unsigned int tlsext_hb_seq', at offset 5440 (in bits) at ssl.h:1303:1
'int renegotiate', at offset 5472 (in bits) at ssl.h:1308:1
6 data member changes (1 filtered):
7 data member changes:
type of 'int version' changed:
entity changed from 'int' to 'SSL*'
type size changed from 32 to 64 (in bits)
@ -305,6 +305,7 @@
entity changed from 'function type void (int, int, int, void*, size_t, SSL*, void*)' to 'typedef SpiceChannelEventInfo' at spice-core.h:88:1
type size changed from 64 to 2560 (in bits)
and name of 'ssl_st::msg_callback' changed to 'RedsStreamPrivate::info' at reds_stream.c:92:1
name of 'ssl_st::msg_callback_arg' changed to 'RedsStreamPrivate::read' at reds_stream.c:94:1, size changed from 0 to 64 (in bits) (by +64 bits)
type of 'int hit' changed:
entity changed from 'int' to 'ssize_t (*)(RedsStream*, void*, size_t)'
type size changed from 32 to 64 (in bits)
@ -560,11 +561,6 @@
7 data member changes:
type of 'void (* pixel_converter)(uint8_t*, uint8_t*)' changed:
in pointed to type 'function type void (uint8_t*, uint8_t*)':
parameter 1 of type 'uint8_t*' changed:
in pointed to type 'typedef uint8_t':
entity changed from 'typedef uint8_t' to compatible type 'void'
type name changed from 'unsigned char' to 'void'
type size changed from 8 to 0 (in bits)
'MJpegEncoderRateControl rate_control' offset changed from 5824 to 5760 (in bits) (by -64 bits)
'MJpegEncoderRateControlCbs cbs' offset changed from 7680 to 7616 (in bits) (by -64 bits)
'void* cbs_opaque' offset changed from 7872 to 7808 (in bits) (by -64 bits)

File diff suppressed because it is too large Load Diff