Remove InputGraph::registerObserver.

PECOFF was the only user of the API, and the reason why we created
the API is because, although the driver creates a list of input files,
it has no knowledge on what files are being created. It was because
everything was hidden behind the InputGraph abstraction.

Now the driver knows what that's doing. We no longer need this
indirection to get the file list being processed.

llvm-svn: 225767
This commit is contained in:
Rui Ueyama 2015-01-13 05:24:53 +00:00
parent d2838c4958
commit 64e3dedf3b
7 changed files with 62 additions and 81 deletions

View File

@ -57,11 +57,6 @@ public:
/// nullptr is returned.
File *getNextFile();
/// Adds an observer of getNextFile(). Each time a new file is about to be
/// returned from getNextFile(), registered observers are called with the file
/// being returned.
void registerObserver(std::function<void(File *)>);
/// \brief Adds a node into the InputGraph
void addInputElement(std::unique_ptr<InputElement>);
@ -89,7 +84,6 @@ protected:
// Index of the next element to be processed
uint32_t _nextElementIndex;
InputElement *_currentInputElement;
std::vector<std::function<void(File *)>> _observers;
private:
InputElement *getNextInputElement();

View File

@ -30,6 +30,28 @@ static const uint8_t DEFAULT_DOS_STUB[128] = {'M', 'Z'};
namespace lld {
namespace pecoff {
class ResolvableSymbols {
public:
void add(File *file);
const std::set<std::string> &defined() {
readAllSymbols();
return _defined;
}
private:
// Files are read lazily, so that it has no runtime overhead if
// no one accesses this class.
void readAllSymbols();
std::set<std::string> _defined;
std::set<File *> _seen;
std::set<File *> _queue;
std::mutex _mutex;
};
} // end namespace pecoff
class PECOFFLinkingContext : public LinkingContext {
public:
PECOFFLinkingContext()
@ -328,6 +350,10 @@ public:
std::recursive_mutex &getMutex() { return _mutex; }
pecoff::ResolvableSymbols *getResolvableSymsFile() {
return &_resolvableSyms;
}
protected:
/// Method to create a internal file for the entry symbol
std::unique_ptr<File> createEntrySymbolFile() const override;
@ -442,6 +468,8 @@ private:
// Name of the temporary file for lib.exe subcommand. For debugging
// only.
std::string _moduleDefinitionFile;
pecoff::ResolvableSymbols _resolvableSyms;
};
} // end namespace lld

View File

@ -20,14 +20,9 @@ File *InputGraph::getNextFile() {
// element points to an archive file, and there's a file left in the archive,
// it will succeed. If not, try to get the next file in the input graph.
for (;;) {
if (_currentInputElement) {
File *next = _currentInputElement->getNextFile();
if (next) {
for (const std::function<void(File *)> &observer : _observers)
observer(next);
if (_currentInputElement)
if (File *next = _currentInputElement->getNextFile())
return next;
}
}
InputElement *elt = getNextInputElement();
if (!elt)
@ -36,10 +31,6 @@ File *InputGraph::getNextFile() {
}
}
void InputGraph::registerObserver(std::function<void(File *)> fn) {
_observers.push_back(fn);
}
void InputGraph::addInputElement(std::unique_ptr<InputElement> ie) {
_inputArgs.push_back(std::move(ie));
}

View File

@ -842,6 +842,7 @@ void addFiles(PECOFFLinkingContext &ctx, StringRef path, raw_ostream &diag,
for (std::unique_ptr<File> &file : loadFile(ctx, path, false)) {
if (ctx.logInputFiles())
diag << file->path() << "\n";
ctx.getResolvableSymsFile()->add(file.get());
files.push_back(std::move(file));
}
}

View File

@ -174,45 +174,6 @@ private:
mutable llvm::BumpPtrAllocator _alloc;
};
class ResolvableSymbols {
public:
void add(File *file) {
std::lock_guard<std::mutex> lock(_mutex);
if (_seen.count(file) > 0)
return;
_seen.insert(file);
_queue.insert(file);
}
const std::set<std::string> &defined() {
readAllSymbols();
return _defined;
}
private:
// Files are read lazily, so that it has no runtime overhead if
// no one accesses this class.
void readAllSymbols() {
std::lock_guard<std::mutex> lock(_mutex);
for (File *file : _queue) {
if (auto *archive = dyn_cast<ArchiveLibraryFile>(file)) {
for (const std::string &sym : archive->getDefinedSymbols())
_defined.insert(sym);
continue;
}
for (const DefinedAtom *atom : file->defined())
if (!atom->name().empty())
_defined.insert(atom->name());
}
_queue.clear();
}
std::set<std::string> _defined;
std::set<File *> _seen;
std::set<File *> _queue;
std::mutex _mutex;
};
// A ExportedSymbolRenameFile is a virtual archive file for dllexported symbols.
//
// One usually has to specify the exact symbol name to resolve it. That's true
@ -246,7 +207,7 @@ private:
class ExportedSymbolRenameFile : public impl::VirtualArchiveLibraryFile {
public:
ExportedSymbolRenameFile(const PECOFFLinkingContext &ctx,
std::shared_ptr<ResolvableSymbols> syms)
ResolvableSymbols *syms)
: VirtualArchiveLibraryFile("<export>"), _syms(syms),
_ctx(const_cast<PECOFFLinkingContext *>(&ctx)) {
for (PECOFFLinkingContext::ExportDesc &desc : _ctx->getDllExports())
@ -258,7 +219,7 @@ public:
if (_exportedSyms.count(sym) == 0)
return nullptr;
std::string replace;
if (!findDecoratedSymbol(_ctx, _syms.get(), sym.str(), replace))
if (!findDecoratedSymbol(_ctx, _syms, sym.str(), replace))
return nullptr;
for (ExportDesc &exp : _ctx->getDllExports())
@ -271,7 +232,7 @@ public:
private:
std::set<std::string> _exportedSyms;
std::shared_ptr<ResolvableSymbols> _syms;
ResolvableSymbols *_syms;
mutable llvm::BumpPtrAllocator _alloc;
mutable PECOFFLinkingContext *_ctx;
};
@ -284,7 +245,7 @@ private:
class EntryPointFile : public SimpleFile {
public:
EntryPointFile(const PECOFFLinkingContext &ctx,
std::shared_ptr<ResolvableSymbols> syms)
ResolvableSymbols *syms)
: SimpleFile("<entry>"), _ctx(const_cast<PECOFFLinkingContext *>(&ctx)),
_syms(syms), _firstTime(true) {}
@ -316,7 +277,7 @@ private:
StringRef opt = _ctx->getEntrySymbolName();
if (!opt.empty()) {
std::string mangled;
if (findDecoratedSymbol(_ctx, _syms.get(), opt, mangled))
if (findDecoratedSymbol(_ctx, _syms, opt, mangled))
return mangled;
return _ctx->decorateSymbol(opt);
}
@ -341,7 +302,7 @@ private:
if (_syms->defined().count(sym))
return true;
std::string ignore;
return findDecoratedSymbol(_ctx, _syms.get(), sym, ignore);
return findDecoratedSymbol(_ctx, _syms, sym, ignore);
};
switch (_ctx->getSubsystem()) {
@ -372,7 +333,7 @@ private:
PECOFFLinkingContext *_ctx;
atom_collection_vector<UndefinedAtom> _undefinedAtoms;
std::mutex _mutex;
std::shared_ptr<ResolvableSymbols> _syms;
ResolvableSymbols *_syms;
llvm::BumpPtrAllocator _alloc;
bool _firstTime;
};

View File

@ -118,9 +118,7 @@ bool PECOFFLinkingContext::createImplicitFiles(
llvm::make_unique<pecoff::LocallyImportedSymbolFile>(*this));
getInputGraph().addInputElement(std::move(impFileNode));
std::shared_ptr<pecoff::ResolvableSymbols> syms(
new pecoff::ResolvableSymbols());
getInputGraph().registerObserver([=](File *file) { syms->add(file); });
pecoff::ResolvableSymbols* syms = getResolvableSymsFile();
// Create a file for dllexported symbols.
auto exportNode = llvm::make_unique<SimpleFileNode>("<export>");
@ -331,4 +329,27 @@ void PECOFFLinkingContext::addPasses(PassManager &pm) {
pm.add(std::unique_ptr<Pass>(new pecoff::InferSubsystemPass(*this)));
}
void pecoff::ResolvableSymbols::add(File *file) {
std::lock_guard<std::mutex> lock(_mutex);
if (_seen.count(file) > 0)
return;
_seen.insert(file);
_queue.insert(file);
}
void pecoff::ResolvableSymbols::readAllSymbols() {
std::lock_guard<std::mutex> lock(_mutex);
for (File *file : _queue) {
if (auto *archive = dyn_cast<ArchiveLibraryFile>(file)) {
for (const std::string &sym : archive->getDefinedSymbols())
_defined.insert(sym);
continue;
}
for (const DefinedAtom *atom : file->defined())
if (!atom->name().empty())
_defined.insert(atom->name());
}
_queue.clear();
}
} // end namespace lld

View File

@ -105,18 +105,3 @@ TEST_F(InputGraphTest, Normalize) {
EXPECT_EQ("file3", getNext());
expectEnd();
}
TEST_F(InputGraphTest, Observer) {
std::vector<std::string> files;
_graph->registerObserver([&](File *file) { files.push_back(file->path()); });
_graph->addInputElement(createFile("file1"));
_graph->addInputElement(createFile("file2"));
EXPECT_EQ("file1", getNext());
EXPECT_EQ("file2", getNext());
expectEnd();
EXPECT_EQ(2U, files.size());
EXPECT_EQ("file1", files[0]);
EXPECT_EQ("file2", files[1]);
}