forked from OSchip/llvm-project
Add PassManager.
It owns and manages passes. llvm-svn: 173287
This commit is contained in:
parent
6c926ccbd2
commit
c0d3c4efe6
|
@ -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
|
|
@ -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 {
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -5,6 +5,7 @@ add_lld_library(lldCore
|
|||
Error.cpp
|
||||
File.cpp
|
||||
InputFiles.cpp
|
||||
PassManager.cpp
|
||||
Resolver.cpp
|
||||
SymbolTable.cpp
|
||||
TargetInfo.cpp
|
||||
|
|
|
@ -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
|
|
@ -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>
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue