From 6149fb02d00d723c6dc99e059a10ea38fb70f928 Mon Sep 17 00:00:00 2001 From: Dodji Seketeli Date: Thu, 13 Jun 2019 11:16:53 +0200 Subject: [PATCH] [dwarf-reader] Re-use function types inside a given TU Whenever we see a function type inside a translation unit, if it matches one that has already been seen -- i.e, one that has the same textual representation -- we should be able to re-use that same function type without having to compare their types to be sure they are the same, as part of the type canonicalization process. This slittly increases analysis speed (by a few tens of seconds on a total of 8 minutes) by decreasing the load on type canonicalization when anlyzing vmlinux. It also slightly reduces memory consumption, so I am getting it in for now. * src/abg-dwarf-reader.cc (istring_fn_type_map_type): Declare new typedef. (die_is_function_type): Define new static function. (read_context::per_tu_repr_to_fn_type_maps_): Define new data member ... (read_context::per_tu_repr_to_fn_type_maps): ... and its accessor. (read_context::{associate_die_repr_to_fn_type_per_tu, lookup_fn_type_from_die_repr_per_tu}): Define new member functions. (build_function_type): Use the new read_context::lookup_fn_type_from_die_repr_per_tu and read_context::associate_die_repr_to_fn_type_per_tu functions, instead of read_context::lookup_type_from_die. * tests/data/test-annotate/test13-pr18894.so.abi: Adjust. * tests/data/test-annotate/test14-pr18893.so.abi: Adjust. * tests/data/test-annotate/test21-pr19092.so.abi: Adjust. * tests/data/test-read-dwarf/test13-pr18894.so.abi: Adjust. * tests/data/test-read-dwarf/test14-pr18893.so.abi: Adjust. * tests/data/test-read-dwarf/test16-pr18904.so.abi: Adjust. * tests/data/test-read-dwarf/test21-pr19092.so.abi: Adjust. Signed-off-by: Dodji Seketeli --- src/abg-dwarf-reader.cc | 118 +++++++++-- .../data/test-annotate/test13-pr18894.so.abi | 188 +++++++++--------- .../data/test-annotate/test14-pr18893.so.abi | 16 +- .../data/test-annotate/test21-pr19092.so.abi | 16 +- .../test-read-dwarf/test13-pr18894.so.abi | 188 +++++++++--------- .../test-read-dwarf/test14-pr18893.so.abi | 16 +- .../test-read-dwarf/test16-pr18904.so.abi | 8 +- .../test-read-dwarf/test21-pr19092.so.abi | 16 +- 8 files changed, 323 insertions(+), 243 deletions(-) diff --git a/src/abg-dwarf-reader.cc b/src/abg-dwarf-reader.cc index 2a65815d..e6979a86 100644 --- a/src/abg-dwarf-reader.cc +++ b/src/abg-dwarf-reader.cc @@ -177,6 +177,12 @@ typedef shared_ptr address_set_sptr; /// addr_elf_symbol_sptr_map_type. typedef shared_ptr addr_elf_symbol_sptr_map_sptr; +/// Convenience typedef for a map that associates and @ref +/// interned_string to a @ref function_type_sptr. +typedef unordered_map istring_fn_type_map_type; + /// Convenience typedef for a stack containing the scopes up to the /// current point in the abigail Internal Representation (aka IR) tree /// that is being built. @@ -345,6 +351,9 @@ die_is_class_type(Dwarf_Die* die); static bool die_is_qualified_type(const Dwarf_Die* die); +static bool +die_is_function_type(const Dwarf_Die *die); + static bool die_has_object_pointer(const Dwarf_Die* die, Dwarf_Die& object_pointer); @@ -3104,6 +3113,10 @@ public: /// the offset of a decl DIE to the offset of its canonical DIE. mutable die_source_dependant_container_set canonical_decl_die_offsets_; + /// A map that associates a function type representations to + /// function types, inside a translation unit. + mutable istring_fn_type_map_type per_tu_repr_to_fn_type_maps_; + die_class_or_union_map_type die_wip_classes_map_; die_class_or_union_map_type alternate_die_wip_classes_map_; die_class_or_union_map_type type_unit_die_wip_classes_map_; @@ -3357,6 +3370,7 @@ public: while (!scope_stack().empty()) scope_stack().pop(); var_decls_to_re_add_to_tree().clear(); + per_tu_repr_to_fn_type_maps().clear(); } /// Clear the data that is relevant for the current corpus being @@ -4787,6 +4801,71 @@ public: type_die_artefact_maps() const {return type_die_artefact_maps_;} + /// Getter of the maps that associates function type representations + /// to function types, inside a translation unit. + /// + /// @return the maps that associates function type representations + /// to function types, inside a translation unit. + istring_fn_type_map_type& + per_tu_repr_to_fn_type_maps() + {return per_tu_repr_to_fn_type_maps_;} + + /// Getter of the maps that associates function type representations + /// to function types, inside a translation unit. + /// + /// @return the maps that associates function type representations + /// to function types, inside a translation unit. + const istring_fn_type_map_type& + per_tu_repr_to_fn_type_maps() const + {return per_tu_repr_to_fn_type_maps_;} + + /// Associate the representation of a function type DIE to a given + /// function type, inside the current translation unit. + /// + /// @param die the DIE to associate to the function type, using its + /// representation. + /// + /// @param fn_type the function type to associate to @p die. + void + associate_die_repr_to_fn_type_per_tu(const Dwarf_Die *die, + const function_type_sptr &fn_type) + { + if (!die_is_function_type(die)) + return; + + interned_string repr = + get_die_pretty_type_representation(die, /*where=*/0); + ABG_ASSERT(!repr.empty()); + + per_tu_repr_to_fn_type_maps()[repr]= fn_type; + } + + /// Lookup the function type associated to a given function type + /// DIE, in the current translation unit. + /// + /// @param die the DIE of function type to consider. + /// + /// @return the @ref function_type_sptr associated to @p die, or nil + /// of no function_type is associated to @p die. + function_type_sptr + lookup_fn_type_from_die_repr_per_tu(const Dwarf_Die *die) + { + if (!die_is_function_type(die)) + return function_type_sptr(); + + interned_string repr = + get_die_pretty_representation(die, /*where=*/0); + ABG_ASSERT(!repr.empty()); + + istring_fn_type_map_type::const_iterator i = + per_tu_repr_to_fn_type_maps().find(repr); + + if (i == per_tu_repr_to_fn_type_maps().end()) + return function_type_sptr(); + + return i->second; + } + /// Set the canonical DIE offset of a given DIE. /// /// @param canonical_dies the vector that holds canonical DIEs. @@ -9487,6 +9566,21 @@ die_is_qualified_type(const Dwarf_Die* die) return false; } +/// Test if a DIE is for a function type. +/// +/// @param die the DIE to consider. +/// +/// @return true iff @p die is for a function type. +static bool +die_is_function_type(const Dwarf_Die *die) +{ + int tag = dwarf_tag(const_cast(die)); + if (tag == DW_TAG_subprogram || tag == DW_TAG_subroutine_type) + return true; + + return false; +} + /// Test if a DIE for a function pointer or member function has an /// DW_AT_object_pointer attribute. /// @@ -14935,9 +15029,10 @@ build_function_type(read_context& ctxt, translation_unit_sptr tu = ctxt.cur_transl_unit(); ABG_ASSERT(tu); - // The call to build_ir_node_from_die() could have triggered the - // creation of the type for this DIE. In that case, just return it. - if (type_base_sptr t = ctxt.lookup_type_from_die(die)) + /// If, inside the current translation unit, we've already seen a + /// function type with the same text representation, then reuse that + /// one instead. + if (type_base_sptr t = ctxt.lookup_fn_type_from_die_repr_per_tu(die)) { result = is_function_type(t); ABG_ASSERT(result); @@ -14962,22 +15057,6 @@ build_function_type(read_context& ctxt, return fn_type; } } - else - { - // We cannot rely on the One Definition Rule across the entire - // binary. But then we can still say that inside the current - // *translation unit*, if two function types have the same name - // (rather representation) then they designate the same type. - // Thus, if we've already seen a DIE with the same - // representation as the one of 'die', then it designates the - // same function type. - if (function_type_sptr fn_type = - is_function_type(ctxt.lookup_type_from_die(die))) - { - ctxt.associate_die_to_type(die, fn_type, where_offset); - return fn_type; - } - } // Let's look at the DIE to detect if it's the DIE for a method // (type). If it is, we can deduce the name of its enclosing class @@ -15026,6 +15105,7 @@ build_function_type(read_context& ctxt, /*alignment=*/0)); ctxt.associate_die_to_type(die, result, where_offset); ctxt.die_wip_function_types_map(source)[dwarf_dieoffset(die)] = result; + ctxt.associate_die_repr_to_fn_type_per_tu(die, result); type_base_sptr return_type; Dwarf_Die ret_type_die; diff --git a/tests/data/test-annotate/test13-pr18894.so.abi b/tests/data/test-annotate/test13-pr18894.so.abi index 6c666dcc..56fd22e6 100644 --- a/tests/data/test-annotate/test13-pr18894.so.abi +++ b/tests/data/test-annotate/test13-pr18894.so.abi @@ -685,11 +685,11 @@ - + - + - + @@ -815,9 +815,9 @@ - + - + @@ -1288,14 +1288,14 @@ - + - + @@ -1311,48 +1311,48 @@ - + - + - + - + - + - + - + - + - + @@ -1450,28 +1450,28 @@ - + - + - + - + - + - + - + - + - + @@ -1513,9 +1513,9 @@ - + - + @@ -1587,9 +1587,9 @@ - + - + @@ -1706,9 +1706,9 @@ - + - + @@ -1722,7 +1722,7 @@ - + @@ -1787,7 +1787,7 @@ - + @@ -1840,7 +1840,7 @@ - + @@ -1887,9 +1887,9 @@ - + - + @@ -1946,9 +1946,9 @@ - + - + @@ -2071,7 +2071,7 @@ - + @@ -2173,14 +2173,14 @@ - + - + @@ -2210,30 +2210,30 @@ - + - + - + - + - + @@ -2249,32 +2249,32 @@ - + - + - + - + - + - + @@ -2295,9 +2295,9 @@ - + - + @@ -2313,9 +2313,9 @@ - + - + @@ -2331,27 +2331,27 @@ - + - + - + - + - + - + @@ -2367,9 +2367,9 @@ - + - + @@ -2383,7 +2383,7 @@ - + @@ -2399,9 +2399,9 @@ - + - + @@ -2553,7 +2553,7 @@ - + @@ -2585,7 +2585,7 @@ - + @@ -2599,7 +2599,7 @@ - + @@ -2664,9 +2664,9 @@ - + - + @@ -2684,11 +2684,11 @@ - + - + - + @@ -2943,7 +2943,7 @@ - + @@ -2964,7 +2964,7 @@ - + @@ -3189,14 +3189,14 @@ - + - + @@ -3255,7 +3255,7 @@ - + @@ -3384,14 +3384,14 @@ - + - + @@ -3477,36 +3477,36 @@ - + - + - + - + - + - + - + - + @@ -3586,7 +3586,7 @@ - + @@ -3902,14 +3902,14 @@ - + - + @@ -3966,7 +3966,7 @@ - + diff --git a/tests/data/test-annotate/test14-pr18893.so.abi b/tests/data/test-annotate/test14-pr18893.so.abi index 97a0096f..e35584dc 100644 --- a/tests/data/test-annotate/test14-pr18893.so.abi +++ b/tests/data/test-annotate/test14-pr18893.so.abi @@ -543,18 +543,18 @@ - + - + - + - + @@ -1301,7 +1301,7 @@ - + @@ -1326,7 +1326,7 @@ - + @@ -1340,7 +1340,7 @@ - + @@ -1358,7 +1358,7 @@ - + diff --git a/tests/data/test-annotate/test21-pr19092.so.abi b/tests/data/test-annotate/test21-pr19092.so.abi index c38fc5ea..da1904bc 100644 --- a/tests/data/test-annotate/test21-pr19092.so.abi +++ b/tests/data/test-annotate/test21-pr19092.so.abi @@ -10287,7 +10287,7 @@ - + @@ -10395,7 +10395,7 @@ - + @@ -10459,13 +10459,13 @@ - + - + - + - + @@ -10581,7 +10581,7 @@ - + @@ -11141,7 +11141,7 @@ - + diff --git a/tests/data/test-read-dwarf/test13-pr18894.so.abi b/tests/data/test-read-dwarf/test13-pr18894.so.abi index d71df251..c83464ad 100644 --- a/tests/data/test-read-dwarf/test13-pr18894.so.abi +++ b/tests/data/test-read-dwarf/test13-pr18894.so.abi @@ -373,9 +373,9 @@ - - - + + + @@ -446,8 +446,8 @@ - - + + @@ -760,11 +760,11 @@ - + - + @@ -773,30 +773,30 @@ - + - - + + - + - - + + - + - - + + @@ -856,18 +856,18 @@ - - - - + + + + - - - - - + + + + + @@ -890,8 +890,8 @@ - - + + @@ -930,8 +930,8 @@ - - + + @@ -993,8 +993,8 @@ - - + + @@ -1002,7 +1002,7 @@ - + @@ -1041,7 +1041,7 @@ - + @@ -1071,7 +1071,7 @@ - + @@ -1097,8 +1097,8 @@ - - + + @@ -1129,8 +1129,8 @@ - - + + @@ -1199,7 +1199,7 @@ - + @@ -1257,11 +1257,11 @@ - + - + @@ -1278,20 +1278,20 @@ - + - - + + - + - + @@ -1300,21 +1300,21 @@ - + - - + + - + - - + + @@ -1326,8 +1326,8 @@ - - + + @@ -1336,8 +1336,8 @@ - - + + @@ -1346,18 +1346,18 @@ - - + + - - + + - - + + @@ -1366,8 +1366,8 @@ - - + + @@ -1375,7 +1375,7 @@ - + @@ -1384,8 +1384,8 @@ - - + + @@ -1480,7 +1480,7 @@ - + @@ -1498,7 +1498,7 @@ - + @@ -1506,7 +1506,7 @@ - + @@ -1546,8 +1546,8 @@ - - + + @@ -1557,9 +1557,9 @@ - - - + + + @@ -1711,7 +1711,7 @@ - + @@ -1723,7 +1723,7 @@ - + @@ -1867,11 +1867,11 @@ - + - + @@ -1903,7 +1903,7 @@ - + @@ -1981,11 +1981,11 @@ - + - + @@ -2034,23 +2034,23 @@ - - + + - - + + - - + + - - + + @@ -2102,7 +2102,7 @@ - + @@ -2301,11 +2301,11 @@ - + - + @@ -2338,7 +2338,7 @@ - + diff --git a/tests/data/test-read-dwarf/test14-pr18893.so.abi b/tests/data/test-read-dwarf/test14-pr18893.so.abi index 75b1f8fa..32ff6615 100644 --- a/tests/data/test-read-dwarf/test14-pr18893.so.abi +++ b/tests/data/test-read-dwarf/test14-pr18893.so.abi @@ -293,13 +293,13 @@ - - + + - - + + @@ -796,7 +796,7 @@ - + @@ -810,7 +810,7 @@ - + @@ -818,7 +818,7 @@ - + @@ -828,7 +828,7 @@ - + diff --git a/tests/data/test-read-dwarf/test16-pr18904.so.abi b/tests/data/test-read-dwarf/test16-pr18904.so.abi index 6ce8a11e..e028e33e 100644 --- a/tests/data/test-read-dwarf/test16-pr18904.so.abi +++ b/tests/data/test-read-dwarf/test16-pr18904.so.abi @@ -38281,10 +38281,10 @@ - - - - + + + + diff --git a/tests/data/test-read-dwarf/test21-pr19092.so.abi b/tests/data/test-read-dwarf/test21-pr19092.so.abi index fd4a5af9..8c727233 100644 --- a/tests/data/test-read-dwarf/test21-pr19092.so.abi +++ b/tests/data/test-read-dwarf/test21-pr19092.so.abi @@ -6666,7 +6666,7 @@ - + @@ -6731,7 +6731,7 @@ - + @@ -6765,10 +6765,10 @@ - - - - + + + + @@ -6834,7 +6834,7 @@ - + @@ -7193,7 +7193,7 @@ - + -- 2.43.5