[lld] r232436 - PECOFF: Make FileCOFF:findAtomAt from O(n) to O(1).

Rui Ueyama ruiu at google.com
Mon Mar 16 16:43:11 PDT 2015


Author: ruiu
Date: Mon Mar 16 18:43:11 2015
New Revision: 232436

URL: http://llvm.org/viewvc/llvm-project?rev=232436&view=rev
Log:
PECOFF: Make FileCOFF:findAtomAt from O(n) to O(1).

I knew I cut corners when I wrote this. Turned out that it is
actually slow when a file being read has many symbols. This patch
is to stop doing linear search and instead do map lookup.

Modified:
    lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp

Modified: lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp
URL: http://llvm.org/viewvc/llvm-project/lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp?rev=232436&r1=232435&r2=232436&view=diff
==============================================================================
--- lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp (original)
+++ lld/trunk/lib/ReaderWriter/PECOFF/ReaderCOFF.cpp Mon Mar 16 18:43:11 2015
@@ -196,9 +196,8 @@ private:
 
   // A sorted map to find an atom from a section and an offset within
   // the section.
-  std::map<const coff_section *,
-           std::map<uint32_t, std::vector<COFFDefinedAtom *>>>
-  _definedAtomLocations;
+  std::map<const coff_section *, std::multimap<uint32_t, COFFDefinedAtom *>>
+      _definedAtomLocations;
 
   uint64_t _ordinal;
   llvm::COFF::MachineTypes _machineType;
@@ -696,7 +695,7 @@ std::error_code FileCOFF::AtomizeDefined
         *this, "", sectionName, sectionSize, Atom::scopeTranslationUnit,
         type, isComdat, perms, _merge[section], data, getNextOrdinal());
     atoms.push_back(atom);
-    _definedAtomLocations[section][0].push_back(atom);
+    _definedAtomLocations[section].insert(std::make_pair(0, atom));
     return std::error_code();
   }
 
@@ -709,7 +708,7 @@ std::error_code FileCOFF::AtomizeDefined
         *this, "", sectionName, sectionSize, Atom::scopeTranslationUnit,
         type, isComdat, perms, _merge[section], data, getNextOrdinal());
     atoms.push_back(atom);
-    _definedAtomLocations[section][0].push_back(atom);
+    _definedAtomLocations[section].insert(std::make_pair(0, atom));
   }
 
   for (auto si = symbols.begin(), se = symbols.end(); si != se; ++si) {
@@ -723,7 +722,7 @@ std::error_code FileCOFF::AtomizeDefined
         type, isComdat, perms, _merge[section], data, getNextOrdinal());
     atoms.push_back(atom);
     _symbolAtom[*si] = atom;
-    _definedAtomLocations[section][si->getValue()].push_back(atom);
+    _definedAtomLocations[section].insert(std::make_pair(si->getValue(), atom));
   }
   return std::error_code();
 }
@@ -786,19 +785,19 @@ std::error_code FileCOFF::findAtomAt(con
                                      uint32_t targetAddress,
                                      COFFDefinedFileAtom *&result,
                                      uint32_t &offsetInAtom) {
-  for (auto i : _definedAtomLocations[section]) {
-    uint32_t atomAddress = i.first;
-    std::vector<COFFDefinedAtom *> &atomsAtSameLocation = i.second;
-    COFFDefinedAtom *atom = atomsAtSameLocation.back();
-    if (atomAddress <= targetAddress &&
-        targetAddress < atomAddress + atom->size()) {
-      result = atom;
-      offsetInAtom = targetAddress - atomAddress;
-      return std::error_code();
-    }
-  }
-  // Relocation target is out of range
-  return llvm::object::object_error::parse_failed;
+  auto loc = _definedAtomLocations.find(section);
+  if (loc == _definedAtomLocations.end())
+    return llvm::object::object_error::parse_failed;
+  std::multimap<uint32_t, COFFDefinedAtom *> &map = loc->second;
+
+  auto it = map.upper_bound(targetAddress);
+  if (it == map.begin())
+    return llvm::object::object_error::parse_failed;
+  --it;
+  uint32_t atomAddress = it->first;
+  result = it->second;
+  offsetInAtom = targetAddress - atomAddress;
+  return std::error_code();
 }
 
 /// Find the atom for the symbol that was at the \p index in the symbol





More information about the llvm-commits mailing list