From 00eb257f2e908e5ec81bbe00aeeb42ea4aa4fd79 Mon Sep 17 00:00:00 2001 From: Rui Ueyama Date: Wed, 10 Dec 2014 00:33:00 +0000 Subject: Re-commit r223330: Rewrite InputGraph's Group llvm-svn: 223867 --- lld/lib/Driver/DarwinInputGraph.cpp | 42 ------------------------------------- lld/lib/Driver/DarwinLdDriver.cpp | 6 +++--- lld/lib/Driver/Driver.cpp | 24 ++++++++++----------- lld/lib/Driver/GnuLdDriver.cpp | 27 +++++++++++++----------- lld/lib/Driver/GnuLdInputGraph.cpp | 7 ++++--- lld/lib/Driver/WinLinkDriver.cpp | 10 ++++----- 6 files changed, 38 insertions(+), 78 deletions(-) (limited to 'lld/lib/Driver') diff --git a/lld/lib/Driver/DarwinInputGraph.cpp b/lld/lib/Driver/DarwinInputGraph.cpp index 29466323b28..5bfa29586aa 100644 --- a/lld/lib/Driver/DarwinInputGraph.cpp +++ b/lld/lib/Driver/DarwinInputGraph.cpp @@ -18,48 +18,6 @@ namespace lld { -ErrorOr DarwinInputGraph::getNextFile() { - // The darwin linker processes input files in two phases. The first phase - // links in all object (.o) files in command line order. The second phase - // links in libraries in command line order. If there are still UndefinedAtoms - // the second phase is repeated until notifyProgress() is not called by - // resolver. - for (;;) { - if (_currentInputElement) { - for(;;) { - ErrorOr next = _currentInputElement->getNextFile(); - if (next.getError()) - break; - File *file = &next.get(); - bool fileIsLibrary = isa(file) || - isa(file); - if (fileIsLibrary == _librariesPhase) { - // Return library in library phase and object files in non-lib mode. - return *file; - } - } - } - - if (_nextElementIndex >= _inputArgs.size()) { - // If no more elements, done unless we need to repeat library scan. - if (_librariesPhase && !_repeatLibraries) - return make_error_code(InputGraphError::no_more_files); - // Clear iterations and only look for libraries. - _librariesPhase = true; - _repeatLibraries = false; - _nextElementIndex = 0; - for (auto &ie : _inputArgs) { - ie->resetNextIndex(); - } - } - _currentInputElement = _inputArgs[_nextElementIndex++].get(); - } -} - -void DarwinInputGraph::notifyProgress() { - _repeatLibraries = true; -} - /// \brief Parse the input file to lld::File. std::error_code MachOFileNode::parse(const LinkingContext &ctx, raw_ostream &diagnostics) { diff --git a/lld/lib/Driver/DarwinLdDriver.cpp b/lld/lib/Driver/DarwinLdDriver.cpp index 21cd691a578..6c80c5c8e65 100644 --- a/lld/lib/Driver/DarwinLdDriver.cpp +++ b/lld/lib/Driver/DarwinLdDriver.cpp @@ -83,7 +83,7 @@ static std::string canonicalizePath(StringRef path) { } } -static void addFile(StringRef path, std::unique_ptr &inputGraph, +static void addFile(StringRef path, std::unique_ptr &inputGraph, MachOLinkingContext &ctx, bool loadWholeArchive, bool upwardDylib) { auto node = llvm::make_unique(path, ctx); @@ -185,7 +185,7 @@ static std::error_code parseOrderFile(StringRef orderFilePath, // per line. The prefix is prepended to each partial path. // static std::error_code parseFileList(StringRef fileListPath, - std::unique_ptr &inputGraph, + std::unique_ptr &inputGraph, MachOLinkingContext &ctx, bool forceLoad, raw_ostream &diagnostics) { // If there is a comma, split off . @@ -521,7 +521,7 @@ bool DarwinLdDriver::parse(int argc, const char *argv[], } } - std::unique_ptr inputGraph(new DarwinInputGraph()); + std::unique_ptr inputGraph(new InputGraph()); // Now construct the set of library search directories, following ld64's // baroque set of accumulated hacks. Mostly, the algorithm constructs diff --git a/lld/lib/Driver/Driver.cpp b/lld/lib/Driver/Driver.cpp index 148d1003218..b26ab251659 100644 --- a/lld/lib/Driver/Driver.cpp +++ b/lld/lib/Driver/Driver.cpp @@ -62,9 +62,6 @@ bool Driver::link(LinkingContext &context, raw_ostream &diagnostics) { if (std::error_code ec = ie->parse(context, stream)) { if (FileNode *fileNode = dyn_cast(ie.get())) stream << fileNode->errStr(ec) << "\n"; - else if (dyn_cast(ie.get())) - // FIXME: We need a better diagnostics here - stream << "Cannot parse group input element\n"; else llvm_unreachable("Unknown type of input element"); fail = true; @@ -83,21 +80,24 @@ bool Driver::link(LinkingContext &context, raw_ostream &diagnostics) { if (fail) return false; - std::unique_ptr fileNode( - new SimpleFileNode("Internal Files")); - InputGraph::FileVectorT internalFiles; context.createInternalFiles(internalFiles); - - if (internalFiles.size()) - fileNode->addFiles(std::move(internalFiles)); + for (auto i = internalFiles.rbegin(), e = internalFiles.rend(); i != e; ++i) { + context.getInputGraph().addInputElementFront( + llvm::make_unique("internal", std::move(*i))); + } // Give target a chance to add files. InputGraph::FileVectorT implicitFiles; context.createImplicitFiles(implicitFiles); - if (implicitFiles.size()) - fileNode->addFiles(std::move(implicitFiles)); - context.getInputGraph().addInputElementFront(std::move(fileNode)); + for (auto i = implicitFiles.rbegin(), e = implicitFiles.rend(); i != e; ++i) { + context.getInputGraph().addInputElementFront( + llvm::make_unique("implicit", std::move(*i))); + } + + // Give target a chance to sort the input files. + // Mach-O uses this chance to move all object files before library files. + context.maybeSortInputFiles(); // Do core linking. ScopedTask resolveTask(getDefaultDomain(), "Resolve"); diff --git a/lld/lib/Driver/GnuLdDriver.cpp b/lld/lib/Driver/GnuLdDriver.cpp index c309e652082..aab08741d38 100644 --- a/lld/lib/Driver/GnuLdDriver.cpp +++ b/lld/lib/Driver/GnuLdDriver.cpp @@ -295,7 +295,8 @@ bool GnuLdDriver::parse(int argc, const char *argv[], } std::unique_ptr inputGraph(new InputGraph()); - std::stack groupStack; + std::stack groupStack; + int numfiles = 0; ELFFileNode::Attributes attributes; @@ -468,16 +469,21 @@ bool GnuLdDriver::parse(int argc, const char *argv[], break; } - case OPT_start_group: { - std::unique_ptr group(new Group()); - groupStack.push(group.get()); - inputGraph->addInputElement(std::move(group)); + case OPT_start_group: + groupStack.push(numfiles); break; - } - case OPT_end_group: + case OPT_end_group: { + if (groupStack.empty()) { + diagnostics << "stray --end-group\n"; + return false; + } + int startGroupPos = groupStack.top(); + inputGraph->addInputElement( + llvm::make_unique(numfiles - startGroupPos)); groupStack.pop(); break; + } case OPT_z: { StringRef extOpt = inputArg->getValue(); @@ -552,11 +558,8 @@ bool GnuLdDriver::parse(int argc, const char *argv[], } } std::unique_ptr inputFile(inputNode); - if (groupStack.empty()) { - inputGraph->addInputElement(std::move(inputFile)); - } else { - groupStack.top()->addFile(std::move(inputFile)); - } + ++numfiles; + inputGraph->addInputElement(std::move(inputFile)); break; } diff --git a/lld/lib/Driver/GnuLdInputGraph.cpp b/lld/lib/Driver/GnuLdInputGraph.cpp index 6fd1ebd08e8..f1a09220b5c 100644 --- a/lld/lib/Driver/GnuLdInputGraph.cpp +++ b/lld/lib/Driver/GnuLdInputGraph.cpp @@ -91,7 +91,7 @@ std::error_code ELFGNULdScript::parse(const LinkingContext &ctx, auto *group = dyn_cast(c); if (!group) continue; - std::unique_ptr groupStart(new Group()); + size_t numfiles = 0; for (const script::Path &path : group->getPaths()) { // TODO : Propagate Set WholeArchive/dashlPrefix attributes.setAsNeeded(path._asNeeded); @@ -100,9 +100,10 @@ std::error_code ELFGNULdScript::parse(const LinkingContext &ctx, _elfLinkingContext, _elfLinkingContext.allocateString(path._path), attributes); std::unique_ptr inputFile(inputNode); - groupStart.get()->addFile(std::move(inputFile)); + _expandElements.push_back(std::move(inputFile)); + ++numfiles; } - _expandElements.push_back(std::move(groupStart)); + _expandElements.push_back(llvm::make_unique(numfiles)); } return std::error_code(); } diff --git a/lld/lib/Driver/WinLinkDriver.cpp b/lld/lib/Driver/WinLinkDriver.cpp index dc6cc79a9dc..2d98c9fe205 100644 --- a/lld/lib/Driver/WinLinkDriver.cpp +++ b/lld/lib/Driver/WinLinkDriver.cpp @@ -781,7 +781,7 @@ static bool hasLibrary(const PECOFFLinkingContext &ctx, FileNode *fileNode) { ErrorOr path = fileNode->getPath(ctx); if (!path) return false; - for (std::unique_ptr &p : ctx.getLibraryGroup()->elements()) + for (std::unique_ptr &p : ctx.getInputGraph().inputElements()) if (auto *f = dyn_cast(p.get())) if (*path == *f->getPath(ctx)) return true; @@ -1397,10 +1397,8 @@ bool WinLinkDriver::parse(int argc, const char *argv[], ctx.setEntryNode(entry.get()); ctx.getInputGraph().addInputElement(std::move(entry)); - // The container for all library files. - std::unique_ptr group(new PECOFFGroup(ctx)); - ctx.setLibraryGroup(group.get()); - ctx.getInputGraph().addInputElement(std::move(group)); + // Add a group-end marker. + ctx.getInputGraph().addInputElement(llvm::make_unique(0)); } // Add the library files to the library group. @@ -1409,7 +1407,7 @@ bool WinLinkDriver::parse(int argc, const char *argv[], if (isReadingDirectiveSection) if (lib->parse(ctx, diag)) return false; - ctx.getLibraryGroup()->addFile(std::move(lib)); + ctx.addLibraryFile(std::move(lib)); } } -- cgit v1.2.3