This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[gold][patch] Avoid looking up Input_merge_map multiple times
- From: Rafael EspÃndola <rafael dot espindola at gmail dot com>
- To: Binutils <binutils at sourceware dot org>
- Cc: Cary Coutant <ccoutant at google dot com>
- Date: Mon, 9 Feb 2015 14:19:45 -0500
- Subject: [gold][patch] Avoid looking up Input_merge_map multiple times
- Authentication-results: sourceware.org; auth=none
The attached patch (which applies on top of my previous one) avoid
looking up Input_merge_map multiple times when we know were are
processing items from the same input section.
Cheers,
Rafael
diff --git a/gold/merge.cc b/gold/merge.cc
index 3cce843..7a532cc 100644
--- a/gold/merge.cc
+++ b/gold/merge.cc
@@ -33,6 +33,45 @@ namespace gold
// Class Object_merge_map.
+void
+Object_merge_map::Input_merge_map::add_mapping(
+ section_offset_type input_offset, section_size_type length,
+ section_offset_type output_offset) {
+ // Try to merge the new entry in the last one we saw.
+ if (!this->entries.empty())
+ {
+ Input_merge_entry& entry(this->entries.back());
+
+ // Use section_size_type to avoid signed/unsigned warnings.
+ section_size_type input_offset_u = input_offset;
+ section_size_type output_offset_u = output_offset;
+
+ // If this entry is not in order, we need to sort the vector
+ // before looking anything up.
+ if (input_offset_u < entry.input_offset + entry.length)
+ {
+ gold_assert(input_offset < entry.input_offset);
+ gold_assert(input_offset_u + length
+ <= static_cast<section_size_type>(entry.input_offset));
+ this->sorted = false;
+ }
+ else if (entry.input_offset + entry.length == input_offset_u
+ && (output_offset == -1
+ ? entry.output_offset == -1
+ : entry.output_offset + entry.length == output_offset_u))
+ {
+ entry.length += length;
+ return;
+ }
+ }
+
+ Input_merge_entry entry;
+ entry.input_offset = input_offset;
+ entry.length = length;
+ entry.output_offset = output_offset;
+ this->entries.push_back(entry);
+}
+
// Destructor.
Object_merge_map::~Object_merge_map()
@@ -94,39 +133,7 @@ Object_merge_map::add_mapping(unsigned int shndx,
{
Input_merge_map* map = this->get_or_make_input_merge_map(shndx);
- // Try to merge the new entry in the last one we saw.
- if (!map->entries.empty())
- {
- Input_merge_entry& entry(map->entries.back());
-
- // Use section_size_type to avoid signed/unsigned warnings.
- section_size_type input_offset_u = input_offset;
- section_size_type output_offset_u = output_offset;
-
- // If this entry is not in order, we need to sort the vector
- // before looking anything up.
- if (input_offset_u < entry.input_offset + entry.length)
- {
- gold_assert(input_offset < entry.input_offset);
- gold_assert(input_offset_u + length
- <= static_cast<section_size_type>(entry.input_offset));
- map->sorted = false;
- }
- else if (entry.input_offset + entry.length == input_offset_u
- && (output_offset == -1
- ? entry.output_offset == -1
- : entry.output_offset + entry.length == output_offset_u))
- {
- entry.length += length;
- return;
- }
- }
-
- Input_merge_entry entry;
- entry.input_offset = input_offset;
- entry.length = length;
- entry.output_offset = output_offset;
- map->entries.push_back(entry);
+ map->add_mapping(input_offset, length, output_offset);
}
// Get the output offset for an input address.
@@ -339,6 +346,10 @@ Output_merge_data::do_add_input_section(Relobj* object, unsigned int shndx)
this->input_count_ += len / entsize;
+ Object_merge_map* merge_map = object->get_or_create_merge_map();
+ Object_merge_map::Input_merge_map* input_merge_map =
+ merge_map->get_or_make_input_merge_map(shndx);
+
for (section_size_type i = 0; i < len; i += entsize, p += entsize)
{
// Add the constant to the section contents. If we find that it
@@ -357,7 +368,7 @@ Output_merge_data::do_add_input_section(Relobj* object, unsigned int shndx)
}
// Record the offset of this constant in the output section.
- object->add_merge_mapping(shndx, i, entsize, k);
+ input_merge_map->add_mapping(i, entsize, k);
}
// For script processing, we keep the input sections.
@@ -539,6 +550,11 @@ Output_merge_string<Char_type>::finalize_merged_data()
{
section_offset_type last_input_offset = 0;
section_offset_type last_output_offset = 0;
+ Relobj *object = (*l)->object;
+ Object_merge_map* merge_map = object->get_or_create_merge_map();
+ Object_merge_map::Input_merge_map* input_merge_map =
+ merge_map->get_or_make_input_merge_map((*l)->shndx);
+
for (typename Merged_strings::const_iterator p =
(*l)->merged_strings.begin();
p != (*l)->merged_strings.end();
@@ -546,9 +562,9 @@ Output_merge_string<Char_type>::finalize_merged_data()
{
section_size_type length = p->offset - last_input_offset;
if (length > 0)
- (*l)->object->add_merge_mapping((*l)->shndx, last_input_offset,
- length, last_output_offset);
- last_input_offset = p->offset;
+ input_merge_map->add_mapping(last_input_offset, length,
+ last_output_offset);
+ last_input_offset = p->offset;
if (p->stringpool_key != 0)
last_output_offset =
this->stringpool_.get_offset_from_key(p->stringpool_key);
diff --git a/gold/merge.h b/gold/merge.h
index d07c4bd..56c084a 100644
--- a/gold/merge.h
+++ b/gold/merge.h
@@ -81,7 +81,6 @@ class Object_merge_map
Unordered_map<section_offset_type,
typename elfcpp::Elf_types<size>::Elf_Addr>*);
- private:
// Map input section offsets to a length and an output section
// offset. An output section offset of -1 means that this part of
// the input section is being discarded.
@@ -95,17 +94,12 @@ class Object_merge_map
section_offset_type output_offset;
};
- // A less-than comparison routine for Input_merge_entry.
- struct Input_merge_compare
- {
- bool
- operator()(const Input_merge_entry& i1, const Input_merge_entry& i2) const
- { return i1.input_offset < i2.input_offset; }
- };
-
// A list of entries for a particular input section.
struct Input_merge_map
{
+ void add_mapping(section_offset_type input_offset, section_size_type length,
+ section_offset_type output_offset);
+
typedef std::vector<Input_merge_entry> Entries;
// The list of mappings.
@@ -118,6 +112,20 @@ class Object_merge_map
{ }
};
+ // Get or make the Input_merge_map to use for the section SHNDX
+ // with MERGE_MAP.
+ Input_merge_map*
+ get_or_make_input_merge_map(unsigned int shndx);
+
+ private:
+ // A less-than comparison routine for Input_merge_entry.
+ struct Input_merge_compare
+ {
+ bool
+ operator()(const Input_merge_entry& i1, const Input_merge_entry& i2) const
+ { return i1.input_offset < i2.input_offset; }
+ };
+
// Map input section indices to merge maps.
typedef std::map<unsigned int, Input_merge_map*> Section_merge_maps;
@@ -126,11 +134,6 @@ class Object_merge_map
Input_merge_map*
get_input_merge_map(unsigned int shndx);
- // Get or make the Input_merge_map to use for the section SHNDX
- // with MERGE_MAP.
- Input_merge_map*
- get_or_make_input_merge_map(unsigned int shndx);
-
// Any given object file will normally only have a couple of input
// sections with mergeable contents. So we keep the first two input
// section numbers inline, and push any further ones into a map. A
diff --git a/gold/object.cc b/gold/object.cc
index 51ad561..c3eaf77 100644
--- a/gold/object.cc
+++ b/gold/object.cc
@@ -273,13 +273,7 @@ void
Relobj::add_merge_mapping(unsigned int shndx, section_offset_type offset,
section_size_type length,
section_offset_type output_offset) {
- Object_merge_map* object_merge_map = this->merge_map();
- if (object_merge_map == NULL)
- {
- object_merge_map = new Object_merge_map();
- this->set_merge_map(object_merge_map);
- }
-
+ Object_merge_map* object_merge_map = this->get_or_create_merge_map();
object_merge_map->add_mapping(shndx, offset, length, output_offset);
}
@@ -392,6 +386,14 @@ Relobj::finalize_incremental_relocs(Layout* layout, bool clear_counts)
layout->incremental_inputs()->set_reloc_count(rindex);
}
+Object_merge_map*
+Relobj::get_or_create_merge_map()
+{
+ if (!this->object_merge_map_)
+ this->object_merge_map_ = new Object_merge_map();
+ return this->object_merge_map_;
+}
+
// Class Sized_relobj.
// Iterate over local symbols, calling a visitor class V for each GOT offset
diff --git a/gold/object.h b/gold/object.h
index f3394d3..167513b 100644
--- a/gold/object.h
+++ b/gold/object.h
@@ -1206,13 +1206,8 @@ class Relobj : public Object
merge_map() const
{ return this->object_merge_map_; }
- // Set the object merge map.
- void
- set_merge_map(Object_merge_map* object_merge_map)
- {
- gold_assert(this->object_merge_map_ == NULL);
- this->object_merge_map_ = object_merge_map;
- }
+ Object_merge_map*
+ get_or_create_merge_map();
void
add_merge_mapping(unsigned int shndx, section_offset_type offset,