From b34838424a4288cc9afc2128fd93098d03d81152 Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Tue, 13 Jan 2015 21:27:12 +0000 Subject: [PATCH] Remove InputGraph::getNextFile(). getNextFile used to have a complex logic to determine which file should be processed by the Resolver on next iteration. Now, it is just a sequential accessor to the internal array and provides no sensible feature. This patch also removes InputGraph::getGroupSize and InputGraph:: skipGroup to simplify the code. llvm-svn: 225832 --- lld/include/lld/Core/InputGraph.h | 15 +--- lld/include/lld/Core/Resolver.h | 4 +- lld/lib/Core/InputGraph.cpp | 30 ------- lld/lib/Core/Resolver.cpp | 56 ++++++------- lld/unittests/DriverTests/CMakeLists.txt | 1 - lld/unittests/DriverTests/InputGraphTest.cpp | 83 -------------------- 6 files changed, 31 insertions(+), 158 deletions(-) delete mode 100644 lld/unittests/DriverTests/InputGraphTest.cpp diff --git a/lld/include/lld/Core/InputGraph.h b/lld/include/lld/Core/InputGraph.h index 66116b6c218e..1c6972633992 100644 --- a/lld/include/lld/Core/InputGraph.h +++ b/lld/include/lld/Core/InputGraph.h @@ -50,12 +50,6 @@ public: /// \brief Initialize the inputgraph InputGraph() : _index(0) {} - virtual ~InputGraph(); - - /// getNextFile returns the next file that needs to be processed by - /// the resolver. When there are no more files to be processed, an - /// nullptr is returned. - File *getNextFile(); /// \brief Adds a node into the InputGraph void addInputElement(std::unique_ptr); @@ -63,14 +57,7 @@ public: /// \brief Adds a node at the beginning of the InputGraph void addInputElementFront(std::unique_ptr); - InputElementVectorT &inputElements() { - return _inputArgs; - } - - // Returns the current group size if we are at an --end-group. - // Otherwise returns 0. - int getGroupSize(); - void skipGroup(); + InputElementVectorT &inputElements() { return _inputArgs; } // \brief Returns the number of input files. size_t size() const { return _inputArgs.size(); } diff --git a/lld/include/lld/Core/Resolver.h b/lld/include/lld/Core/Resolver.h index 1bde4f9bb0bd..db578fb5b4b9 100644 --- a/lld/include/lld/Core/Resolver.h +++ b/lld/include/lld/Core/Resolver.h @@ -55,8 +55,8 @@ public: private: typedef std::function UndefCallback; - bool undefinesAdded(int count); - File *nextFile(bool &inGroup); + bool undefinesAdded(int begin, int end); + File *getFile(int &index, int &groupLevel); /// \brief Add section group/.gnu.linkonce if it does not exist previously. void maybeAddSectionGroupOrGnuLinkOnce(const DefinedAtom &atom); diff --git a/lld/lib/Core/InputGraph.cpp b/lld/lib/Core/InputGraph.cpp index 0c86bdf2da3d..2041ba513da0 100644 --- a/lld/lib/Core/InputGraph.cpp +++ b/lld/lib/Core/InputGraph.cpp @@ -13,17 +13,6 @@ using namespace lld; -InputGraph::~InputGraph() { } - -File *InputGraph::getNextFile() { - for (;;) { - if (_index >= _inputArgs.size()) - return nullptr; - if (FileNode *node = dyn_cast(_inputArgs[_index++].get())) - return node->getFile(); - } -} - void InputGraph::addInputElement(std::unique_ptr ie) { _inputArgs.push_back(std::move(ie)); } @@ -32,25 +21,6 @@ void InputGraph::addInputElementFront(std::unique_ptr ie) { _inputArgs.insert(_inputArgs.begin(), std::move(ie)); } -// If we are at the end of a group, return its size (which indicates -// how many files we need to go back in the command line). -// Returns 0 if we are not at the end of a group. -int InputGraph::getGroupSize() { - if (_index >= _inputArgs.size()) - return 0; - InputElement *elem = _inputArgs[_index].get(); - if (const GroupEnd *group = dyn_cast(elem)) - return group->getSize(); - return 0; -} - -void InputGraph::skipGroup() { - if (_index >= _inputArgs.size()) - return; - if (isa(_inputArgs[_index].get())) - _index++; -} - std::error_code FileNode::parse(const LinkingContext &, raw_ostream &) { if (_file) if (std::error_code ec = _file->parse()) diff --git a/lld/lib/Core/Resolver.cpp b/lld/lib/Core/Resolver.cpp index 90d141b2f203..49d3f61402cb 100644 --- a/lld/lib/Core/Resolver.cpp +++ b/lld/lib/Core/Resolver.cpp @@ -231,52 +231,52 @@ void Resolver::addAtoms(const std::vector &newAtoms) { // Returns true if at least one of N previous files has created an // undefined symbol. -bool Resolver::undefinesAdded(int n) { - for (size_t i = _fileIndex - n; i < _fileIndex; ++i) - if (_newUndefinesAdded[_files[i]]) - return true; +bool Resolver::undefinesAdded(int begin, int end) { + std::vector> &inputs = + _context.getInputGraph().inputElements(); + for (int i = begin; i < end; ++i) + if (FileNode *node = dyn_cast(inputs[i].get())) + if (_newUndefinesAdded[node->getFile()]) + return true; return false; } -File *Resolver::nextFile(bool &inGroup) { - if (size_t groupSize = _context.getInputGraph().getGroupSize()) { +File *Resolver::getFile(int &index, int &groupLevel) { + std::vector> &inputs + = _context.getInputGraph().inputElements(); + if ((size_t)index >= inputs.size()) + return nullptr; + if (GroupEnd *group = dyn_cast(inputs[index].get())) { // We are at the end of the current group. If one or more new // undefined atom has been added in the last groupSize files, we // reiterate over the files. - if (undefinesAdded(groupSize)) - _fileIndex -= groupSize; - _context.getInputGraph().skipGroup(); - return nextFile(inGroup); + int size = group->getSize(); + if (undefinesAdded(index - size, index)) { + index -= size; + ++groupLevel; + return getFile(index, groupLevel); + } + ++index; + --groupLevel; + return getFile(index, groupLevel); } - if (_fileIndex < _files.size()) { - // We are still in the current group. - inGroup = true; - return _files[_fileIndex++]; - } - // We are not in a group. Get a new file. - File *file = _context.getInputGraph().getNextFile(); - if (!file) - return nullptr; - _files.push_back(&*file); - ++_fileIndex; - inGroup = false; - return file; + return cast(inputs[index++].get())->getFile(); } // Keep adding atoms until _context.getNextFile() returns an error. This // function is where undefined atoms are resolved. void Resolver::resolveUndefines() { ScopedTask task(getDefaultDomain(), "resolveUndefines"); - + int index = 0; + int groupLevel = 0; for (;;) { - bool inGroup = false; bool undefAdded = false; - File *file = nextFile(inGroup); + File *file = getFile(index, groupLevel); if (!file) return; switch (file->kind()) { case File::kindObject: - if (inGroup) + if (groupLevel > 0) break; assert(!file->hasOrdinal()); file->setOrdinal(_context.getNextOrdinalAndIncrement()); @@ -293,7 +293,7 @@ void Resolver::resolveUndefines() { handleSharedLibrary(*file); break; } - _newUndefinesAdded[&*file] = undefAdded; + _newUndefinesAdded[file] = undefAdded; } } diff --git a/lld/unittests/DriverTests/CMakeLists.txt b/lld/unittests/DriverTests/CMakeLists.txt index 57d81ae38de2..11edf349cc7c 100644 --- a/lld/unittests/DriverTests/CMakeLists.txt +++ b/lld/unittests/DriverTests/CMakeLists.txt @@ -4,7 +4,6 @@ add_lld_unittest(DriverTests DarwinLdDriverTest.cpp WinLinkDriverTest.cpp WinLinkModuleDefTest.cpp - InputGraphTest.cpp ) target_link_libraries(DriverTests diff --git a/lld/unittests/DriverTests/InputGraphTest.cpp b/lld/unittests/DriverTests/InputGraphTest.cpp deleted file mode 100644 index a870a9ccc072..000000000000 --- a/lld/unittests/DriverTests/InputGraphTest.cpp +++ /dev/null @@ -1,83 +0,0 @@ -//===- lld/unittest/InputGraphTest.cpp -----------------------------------===// -// -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -/// -/// \file -/// \brief InputGraph Tests -/// -//===----------------------------------------------------------------------===// - -#include "gtest/gtest.h" -#include "lld/Core/InputGraph.h" -#include "lld/Core/Resolver.h" -#include "lld/Core/Simple.h" - -using namespace lld; - -namespace { - -class TestLinkingContext : public LinkingContext { -public: - Writer &writer() const override { llvm_unreachable("no writer!"); } - bool validateImpl(raw_ostream &) override { return true; } -}; - -class TestExpandFileNode : public SimpleFileNode { -public: - TestExpandFileNode(StringRef path) : SimpleFileNode(path) {} - - void addElement(std::unique_ptr element) { - _expandElements.push_back(std::move(element)); - } - -private: - InputGraph::InputElementVectorT _expandElements; -}; - -class InputGraphTest : public testing::Test { -public: - InputGraphTest() { - _ctx.setInputGraph(std::unique_ptr(new InputGraph())); - _graph = &_ctx.getInputGraph(); - } - - StringRef getNext() { - File *file = _graph->getNextFile(); - EXPECT_TRUE(file); - return file->path(); - } - - void expectEnd() { - File *file = _graph->getNextFile(); - EXPECT_TRUE(file == nullptr); - } - -protected: - TestLinkingContext _ctx; - InputGraph *_graph; -}; - -} // end anonymous namespace - -static std::unique_ptr createFile(StringRef name) { - std::vector> files; - files.push_back(std::unique_ptr(new SimpleFile(name))); - std::unique_ptr file(new SimpleFileNode("filenode")); - file->addFiles(std::move(files)); - return file; -} - -TEST_F(InputGraphTest, Empty) { - expectEnd(); -} - -TEST_F(InputGraphTest, File) { - _graph->addInputElement(createFile("file1")); - EXPECT_EQ("file1", getNext()); - expectEnd(); -}