Add PassManager.

It owns and manages passes.

llvm-svn: 173287
This commit is contained in:
Michael J. Spencer 2013-01-23 20:03:10 +00:00
parent 6c926ccbd2
commit c0d3c4efe6
10 changed files with 92 additions and 62 deletions

View File

@ -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

View 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 {

View File

@ -17,10 +17,8 @@
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.

View File

@ -5,6 +5,7 @@ add_lld_library(lldCore
Error.cpp
File.cpp
InputFiles.cpp
PassManager.cpp
Resolver.cpp
SymbolTable.cpp
TargetInfo.cpp

View File

@ -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

View 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>

View 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"

View 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);
}

View 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;
};

View 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;