[PATCH] [lld][Driver] Parallelize reading initial object files.

Michael Spencer bigcheesegs at gmail.com
Fri Apr 12 13:21:50 PDT 2013



================
Comment at: lib/Driver/Driver.cpp:47
@@ +46,3 @@
+  size_t index = 0;
+  std::atomic<bool> fail(false);
+  TaskGroup tg;
----------------
Shankar Kalpathi Easwaran wrote:
> Why you want this to be atomic bool ? because you are only setting the value to be true and the check/return is done only after all the threads have got synced ? 
> 
> Also it would be essential to check if there was a failure reading one of the files before reading the next set of files.
> 
> For example:
> 
> Say thread concurrency = 2
> 
> TG created 2 threads and there were 4 files
> 
> Say there was an error reading file 1 (or) file 2. You could stop file 3/4 from being read.
It has to be atomic because it could be written from multiple threads.

I don't see why it's essential to early exit the other tasks. It is indeed possible though. Just check the value of fail.

================
Comment at: lib/Driver/Driver.cpp:62-67
@@ +61,8 @@
+
+      std::unique_ptr<MemoryBuffer> buff(MemoryBuffer::getMemBuffer(
+          buffer->getBuffer(), buffer->getBufferIdentifier()));
+      if (error_code ec = targetInfo.parseFile(buff, files[index])) {
+        diagnostics << "Failed to read file: " << input.getPath()
+                    << ": " << ec.message() << "\n";
+        fail = true;
+        return;
----------------
Shankar Kalpathi Easwaran wrote:
> Isnt using index a problem with archive files.
> 
> --force-load-archive option / multiple archive files getting pulled in ?
files is a std::vector<std::vector<std::unique_ptr<File>>>. Each input argument gets a std::vector.

================
Comment at: lib/ReaderWriter/ELF/ELFTargetInfo.cpp:95-120
@@ -94,22 +94,28 @@
 
 error_code ELFTargetInfo::parseFile(std::unique_ptr<MemoryBuffer> &mb,
                           std::vector<std::unique_ptr<File>> &result) const {
+  std::unique_lock<std::mutex> lock(_readerMutex);
   if (!_elfReader)
     _elfReader = createReaderELF(*this);
+  lock.unlock();
   error_code ec = _elfReader->parseFile(mb, result);
   if (ec) {
     // Not an ELF file, check file extension to see if it might be yaml
     StringRef path = mb->getBufferIdentifier();
-    if ( path.endswith(".objtxt") ) {
+    if (path.endswith(".objtxt")) {
+      lock.lock();
       if (!_yamlReader)
           _yamlReader = createReaderYAML(*this);
+      lock.unlock();
       ec = _yamlReader->parseFile(mb, result);
     }
     if (ec) {
       // Not a yaml file, assume it is a linkerscript
+      lock.lock();
       if (!_linkerScriptReader)
         _linkerScriptReader.reset(new ReaderLinkerScript(*this));
+      lock.unlock();
       ec = _linkerScriptReader->parseFile(mb, result);
     }
   }
   return ec;
----------------
Shankar Kalpathi Easwaran wrote:
> I think we could create the _elfReader/_yamlReader/_linkerScriptReader as soon as ELFTargetInfo is initialized. Because after the first time the _elfReader/_yamlReader/_linkerScriptReader is initialized, you dont need the locks. This implementation will lock them and make it slower too, because of the locks / unlocks being done multiple times.
k

================
Comment at: lib/ReaderWriter/ELF/File.h:314
@@ -310,1 +313,3 @@
 
+    // Iterate over sections by object file position. The pointers point into
+    // the memory mapped file, so it's valid to sort based on them.
----------------
Shankar Kalpathi Easwaran wrote:
> did you mean iterate over sections by their positions in the object file ?
Yes, that's what that says.

================
Comment at: lib/ReaderWriter/ELF/File.h:315-325
@@ -311,2 +314,13 @@
+    // Iterate over sections by object file position. The pointers point into
+    // the memory mapped file, so it's valid to sort based on them.
+    std::vector<typename SectionSymbolsT::value_type *> secSyms;
+    secSyms.reserve(sectionSymbols.size());
     for (auto &i : sectionSymbols) {
-      auto &symbols = i.second;
+      secSyms.push_back(&i);
+    }
+    std::sort(secSyms.begin(), secSyms.end(),
+              [](const typename SectionSymbolsT::value_type *a,
+                 const typename SectionSymbolsT::value_type *b) {
+       return a->first < b->first;
+    });
+
----------------
Shankar Kalpathi Easwaran wrote:
> Was there an issue earlier ?
I changed sectionSymbols to a DenseMap instead of a std::map. This is required because DenseMap is unordered.


http://llvm-reviews.chandlerc.com/D664



More information about the llvm-commits mailing list