Add PassManager.
authorMichael J. Spencer <bigcheesegs@gmail.com>
Wed, 23 Jan 2013 20:03:10 +0000 (20:03 +0000)
committerMichael J. Spencer <bigcheesegs@gmail.com>
Wed, 23 Jan 2013 20:03:10 +0000 (20:03 +0000)
It owns and manages passes.

llvm-svn: 173287

lld/include/lld/Core/PassManager.h [new file with mode: 0644]
lld/include/lld/Core/TargetInfo.h
lld/include/lld/ReaderWriter/Writer.h
lld/lib/Core/CMakeLists.txt
lld/lib/Core/PassManager.cpp [new file with mode: 0644]
lld/lib/ReaderWriter/MachO/MachOTargetInfo.cpp
lld/lib/ReaderWriter/MachO/StubsPass.hpp
lld/lib/ReaderWriter/MachO/WriterMachO.cpp
lld/lib/ReaderWriter/YAML/ReaderWriterYAML.cpp
lld/tools/lld-core/lld-core.cpp

diff --git a/lld/include/lld/Core/PassManager.h b/lld/include/lld/Core/PassManager.h
new file mode 100644 (file)
index 0000000..25e90cb
--- /dev/null
@@ -0,0 +1,42 @@
+//===- lld/Core/PassManager.h - Manage linker passes ----------------------===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLD_CORE_PASS_MANAGER_H
+#define LLD_CORE_PASS_MANAGER_H
+
+#include "lld/Core/LLVM.h"
+
+#include <memory>
+#include <vector>
+
+namespace lld {
+class MutableFile;
+class Pass;
+
+/// \brief Owns and runs a collection of passes.
+///
+/// This class is currently just a container for passes and a way to run them.
+///
+/// In the future this should handle timing pass runs, running parallel passes,
+/// and validate/satisfy pass dependencies.
+class PassManager {
+public:
+  void add(std::unique_ptr<Pass> pass) {
+    _passes.push_back(std::move(pass));
+  }
+
+  ErrorOr<void> runOnFile(MutableFile &);
+
+private:
+  /// \brief Passes in the order they should run.
+  std::vector<std::unique_ptr<Pass>> _passes;
+};
+} // end namespace lld
+
+#endif
index 6be71fc..8d7adf7 100644 (file)
@@ -32,8 +32,7 @@ namespace llvm {
 
 namespace lld {
 struct LinkerOptions;
-class GOTPass;
-class StubsPass;
+class PassManager;
 
 class TargetInfo {
 protected:
@@ -52,8 +51,7 @@ public:
 
   virtual StringRef getEntry() const;
 
-  virtual StubsPass *getStubPass() const { return nullptr; }
-  virtual GOTPass *getGOTPass() const { return nullptr; }
+  virtual void addPasses(PassManager &pm) const {}
 
   // TODO: Split out to TargetRelocationInfo.
   virtual ErrorOr<int32_t> relocKindFromString(StringRef str) const {
index bfae628..269cff9 100644 (file)
 namespace lld {
 class ELFTargetInfo;
 class File;
-class GOTPass;
 class InputFiles;
 class MachOTargetInfo;
-class StubsPass;
 class TargetInfo;
 
 /// \brief The Writer is an abstract class for writing object files, shared
@@ -33,16 +31,6 @@ public:
   /// \brief Write a file from the supplied File object 
   virtual error_code writeFile(const File &linkedFile, StringRef path) = 0;
   
-  /// \brief Return a Pass object for creating stubs/PLT entries
-  virtual StubsPass *stubPass() {
-    return nullptr;
-  }
-  
-  /// \brief Return a Pass object for creating GOT entries
-  virtual GOTPass *gotPass() {
-    return nullptr;
-  }
-  
   /// \brief This method is called by Core Linking to give the Writer a chance
   /// to add file format specific "files" to set of files to be linked. This is
   /// how file format specific atoms can be added to the link.
index 44becf4..29633ec 100644 (file)
@@ -5,6 +5,7 @@ add_lld_library(lldCore
   Error.cpp
   File.cpp
   InputFiles.cpp
+  PassManager.cpp
   Resolver.cpp
   SymbolTable.cpp
   TargetInfo.cpp
diff --git a/lld/lib/Core/PassManager.cpp b/lld/lib/Core/PassManager.cpp
new file mode 100644 (file)
index 0000000..2dee5ee
--- /dev/null
@@ -0,0 +1,23 @@
+//===- lib/Core/PassManager.cpp - Manage linker passes --------------------===//
+//
+//                             The LLVM Linker
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "lld/Core/PassManager.h"
+
+#include "lld/Core/Pass.h"
+
+#include "llvm/Support/ErrorOr.h"
+
+namespace lld {
+ErrorOr<void> PassManager::runOnFile(MutableFile &mf) {
+  for (auto &pass : _passes) {
+    pass->perform(mf);
+  }
+  return llvm::error_code::success();
+}
+} // end namespace lld
index f374966..f116716 100644 (file)
@@ -8,8 +8,11 @@
 //===----------------------------------------------------------------------===//
 
 #include "lld/ReaderWriter/MachOTargetInfo.h"
+#include "GOTPass.hpp"
+#include "StubsPass.hpp"
 
 #include "lld/Core/LinkerOptions.h"
+#include "lld/Core/PassManager.h"
 
 #include "llvm/ADT/Triple.h"
 #include "llvm/Support/MachO.h"
@@ -73,6 +76,11 @@ public:
       return _options._entrySymbol;
     return "_main";
   }
+
+  virtual void addPasses(PassManager &pm) const {
+    pm.add(std::unique_ptr<Pass>(new mach_o::GOTPass));
+    pm.add(std::unique_ptr<Pass>(new mach_o::StubsPass(*this)));
+  }
 };
 
 std::unique_ptr<MachOTargetInfo>
index 28453cf..ffe5b13 100644 (file)
@@ -13,6 +13,7 @@
 #include "llvm/ADT/DenseMap.h"
 
 #include "lld/Core/DefinedAtom.h"
+#include "lld/Core/LinkerOptions.h"
 #include "lld/Core/SharedLibraryAtom.h"
 #include "lld/Core/File.h"
 #include "lld/Core/Reference.h"
index 64a6be3..1269ac4 100644 (file)
@@ -40,9 +40,6 @@
 #include "MachOFormat.hpp"
 #include "ReferenceKinds.h"
 #include "ExecutableAtoms.hpp"
-#include "GOTPass.hpp"
-#include "StubsPass.hpp"
-
 
 namespace lld {
 namespace mach_o {
@@ -346,8 +343,6 @@ public:
               MachOWriter(const MachOTargetInfo &ti);
 
   virtual error_code  writeFile(const lld::File &file, StringRef path);
-  virtual StubsPass  *stubPass();  
-  virtual GOTPass    *gotPass();  
   virtual void        addFiles(InputFiles&);
 
   uint64_t    addressOfAtom(const Atom *atom);
@@ -378,8 +373,6 @@ private:
 
   const MachOTargetInfo      &_targetInfo;
   KindHandler                *_referenceKindHandler;
-  StubsPass                   _stubsPass;
-  GOTPass                     _gotPass;
   CRuntimeFile                _cRuntimeFile;
   LoadCommandsChunk          *_loadCommandsChunk;
   LoadCommandPaddingChunk    *_paddingChunk;
@@ -1306,7 +1299,7 @@ uint32_t SymbolStringsChunk::stringIndex(StringRef str) {
 MachOWriter::MachOWriter(const MachOTargetInfo &ti)
   : _targetInfo(ti),
     _referenceKindHandler(KindHandler::makeHandler(ti.getTriple().getArch())),
-    _stubsPass(ti), _cRuntimeFile(ti),
+    _cRuntimeFile(ti),
     _bindingInfo(nullptr), _lazyBindingInfo(nullptr),
     _symbolTableChunk(nullptr), _stringsChunk(nullptr), _entryAtom(nullptr),
     _linkEditStartOffset(0), _linkEditStartAddress(0) {
@@ -1525,15 +1518,6 @@ error_code MachOWriter::writeFile(const lld::File &file, StringRef path) {
   return error_code::success();
 }
 
-
-StubsPass *MachOWriter::stubPass() {
-  return &_stubsPass;
-}
-GOTPass *MachOWriter::gotPass() {
-  return &_gotPass;
-}
-
 void MachOWriter::addFiles(InputFiles &inputFiles) {
   inputFiles.prependFile(_cRuntimeFile);
 }
index 30e52d0..7d702c5 100644 (file)
@@ -1281,15 +1281,6 @@ public:
     return error_code::success();
   }
   
-  virtual StubsPass *stubPass() {
-    return _targetInfo.getStubPass();
-  }
-  
-  virtual GOTPass *gotPass() {
-    return _targetInfo.getGOTPass();
-  }
-  
-  
 private:
   const TargetInfo &_targetInfo;
 };
index 11431b0..74a657a 100644 (file)
@@ -11,6 +11,7 @@
 #include "lld/Core/LinkerOptions.h"
 #include "lld/Core/LLVM.h"
 #include "lld/Core/Pass.h"
+#include "lld/Core/PassManager.h"
 #include "lld/Core/Resolver.h"
 #include "lld/ReaderWriter/ELFTargetInfo.h"
 #include "lld/ReaderWriter/MachOTargetInfo.h"
@@ -159,18 +160,11 @@ public:
 
   virtual uint64_t getPageSize() const { return 0x1000; }
 
-  virtual StubsPass *getStubPass() const {
+  virtual void addPasses(PassManager &pm) const {
     if (_doStubs)
-      return const_cast<TestingStubsPass*>(&_stubsPass);
-    else
-      return nullptr;
-  }
-
-  virtual GOTPass *getGOTPass() const {
-     if (_doGOT)
-      return const_cast<TestingGOTPass*>(&_gotPass);
-    else
-      return nullptr;
+      pm.add(std::unique_ptr<Pass>(new TestingStubsPass));
+    if (_doGOT)
+      pm.add(std::unique_ptr<Pass>(new TestingGOTPass));
   }
 
   virtual ErrorOr<int32_t> relocKindFromString(StringRef str) const {
@@ -193,8 +187,6 @@ public:
 private:
   bool              _doStubs;
   bool              _doGOT;
-  TestingStubsPass  _stubsPass;
-  TestingGOTPass    _gotPass;
 };
 
 int main(int argc, char *argv[]) {
@@ -243,18 +235,23 @@ int main(int argc, char *argv[]) {
   std::unique_ptr<ELFTargetInfo> eti = ELFTargetInfo::create(lo);
   std::unique_ptr<MachOTargetInfo> mti = MachOTargetInfo::create(lo);
   std::unique_ptr<Writer> writer;
+  const TargetInfo *ti = 0;
   switch ( writeSelected ) {
     case writeYAML:
       writer = createWriterYAML(tti);
+      ti = &tti;
       break;
     case writeMachO:
       writer = createWriterMachO(*mti);
+      ti = mti.get();
       break;
     case writePECOFF:
       writer = createWriterPECOFF(tti);
+      ti = &tti;
       break;
     case writeELF:
       writer = createWriterELF(*eti);
+      ti = eti.get();
       break;
   }
   
@@ -304,13 +301,10 @@ int main(int argc, char *argv[]) {
   resolver.resolve();
   MutableFile &mergedMasterFile = resolver.resultFile();
 
-  // run passes
-  if ( GOTPass *pass = writer->gotPass() ) {
-    pass->perform(mergedMasterFile);
-  }
-  if ( StubsPass *pass = writer->stubPass() ) {
-    pass->perform(mergedMasterFile);
-  }
+  PassManager pm;
+  if (ti)
+    ti->addPasses(pm);
+  pm.runOnFile(mergedMasterFile);
 
   // showing yaml at this stage can help when debugging
   const bool dumpIntermediateYAML = false;