From: Teresa Johnson <tejohnson@google.com> Date: Mon, 19 Oct 2015 14:30:44 +0000 (+0000) Subject: llvm-lto support for generating combined function indexes X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=d6e77b7d157be995bbcc6b818c3e4a2fd8aa0ee9;p=oota-llvm.git llvm-lto support for generating combined function indexes Summary: This patch adds support to llvm-lto that mirrors the support added by r249270 to the gold plugin. This enables better testing of combined index generation for ThinLTO. Added a new test, and this support will be used in the test in D13515. Reviewers: joker.eph Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D13847 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@250699 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/test/tools/llvm-lto/Inputs/thinlto.ll b/test/tools/llvm-lto/Inputs/thinlto.ll new file mode 100644 index 00000000000..4e0840f3691 --- /dev/null +++ b/test/tools/llvm-lto/Inputs/thinlto.ll @@ -0,0 +1,4 @@ +define void @g() { +entry: + ret void +} diff --git a/test/tools/llvm-lto/thinlto.ll b/test/tools/llvm-lto/thinlto.ll new file mode 100644 index 00000000000..29d3881b9df --- /dev/null +++ b/test/tools/llvm-lto/thinlto.ll @@ -0,0 +1,24 @@ +; Test combined function index generation for ThinLTO via llvm-lto. +; RUN: llvm-as -function-summary %s -o %t.o +; RUN: llvm-as -function-summary %p/Inputs/thinlto.ll -o %t2.o +; RUN: llvm-lto -thinlto -o %t3 %t.o %t2.o +; RUN: llvm-bcanalyzer -dump %t3.thinlto.bc | FileCheck %s --check-prefix=COMBINED +; RUN: not test -e %t3 + +; COMBINED: <MODULE_STRTAB_BLOCK +; COMBINED-NEXT: <ENTRY {{.*}} record string = '{{.*}}/thinlto.ll.tmp{{.*}}.o' +; COMBINED-NEXT: <ENTRY {{.*}} record string = '{{.*}}/thinlto.ll.tmp{{.*}}.o' +; COMBINED-NEXT: </MODULE_STRTAB_BLOCK +; COMBINED-NEXT: <FUNCTION_SUMMARY_BLOCK +; COMBINED-NEXT: <COMBINED_ENTRY +; COMBINED-NEXT: <COMBINED_ENTRY +; COMBINED-NEXT: </FUNCTION_SUMMARY_BLOCK +; COMBINED-NEXT: <VALUE_SYMTAB +; COMBINED-NEXT: <COMBINED_FNENTRY {{.*}} record string = '{{f|g}}' +; COMBINED-NEXT: <COMBINED_FNENTRY {{.*}} record string = '{{f|g}}' +; COMBINED-NEXT: </VALUE_SYMTAB + +define void @f() { +entry: + ret void +} diff --git a/tools/llvm-lto/CMakeLists.txt b/tools/llvm-lto/CMakeLists.txt index 3ea1aeea9a4..6a35dd9a241 100644 --- a/tools/llvm-lto/CMakeLists.txt +++ b/tools/llvm-lto/CMakeLists.txt @@ -1,7 +1,10 @@ set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD} + BitReader + Core LTO MC + Object Support Target ) diff --git a/tools/llvm-lto/LLVMBuild.txt b/tools/llvm-lto/LLVMBuild.txt index c1613a34c0e..a586db6d7f7 100644 --- a/tools/llvm-lto/LLVMBuild.txt +++ b/tools/llvm-lto/LLVMBuild.txt @@ -19,4 +19,4 @@ type = Tool name = llvm-lto parent = Tools -required_libraries = LTO Support all-targets +required_libraries = BitReader Core LTO Object Support all-targets diff --git a/tools/llvm-lto/llvm-lto.cpp b/tools/llvm-lto/llvm-lto.cpp index 50680ccb8ab..29d613f8cd2 100644 --- a/tools/llvm-lto/llvm-lto.cpp +++ b/tools/llvm-lto/llvm-lto.cpp @@ -13,9 +13,12 @@ //===----------------------------------------------------------------------===// #include "llvm/ADT/StringSet.h" +#include "llvm/Bitcode/ReaderWriter.h" #include "llvm/CodeGen/CommandFlags.h" +#include "llvm/IR/LLVMContext.h" #include "llvm/LTO/LTOCodeGenerator.h" #include "llvm/LTO/LTOModule.h" +#include "llvm/Object/FunctionIndexObjectFile.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/ManagedStatic.h" @@ -56,6 +59,10 @@ static cl::opt<bool> UseDiagnosticHandler("use-diagnostic-handler", cl::init(false), cl::desc("Use a diagnostic handler to test the handler interface")); +static cl::opt<bool> ThinLTO( + "thinlto", cl::init(false), + cl::desc("Only write combined global index for ThinLTO backends")); + static cl::list<std::string> InputFilenames(cl::Positional, cl::OneOrMore, cl::desc("<input bitcode files>")); @@ -151,6 +158,61 @@ static int listSymbols(StringRef Command, const TargetOptions &Options) { return 0; } +/// Parse the function index out of an IR file and return the function +/// index object if found, or nullptr if not. +static std::unique_ptr<FunctionInfoIndex> getFunctionIndexForFile( + StringRef Path, std::string &Error, LLVMContext &Context) { + std::unique_ptr<MemoryBuffer> Buffer; + ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr = + MemoryBuffer::getFile(Path); + if (std::error_code EC = BufferOrErr.getError()) { + Error = EC.message(); + return nullptr; + } + Buffer = std::move(BufferOrErr.get()); + ErrorOr<std::unique_ptr<object::FunctionIndexObjectFile>> ObjOrErr = + object::FunctionIndexObjectFile::create(Buffer->getMemBufferRef(), + Context); + if (std::error_code EC = ObjOrErr.getError()) { + Error = EC.message(); + return nullptr; + } + return (*ObjOrErr)->takeIndex(); +} + +/// Create a combined index file from the input IR files and write it. +/// +/// This is meant to enable testing of ThinLTO combined index generation, +/// currently available via the gold plugin via -thinlto. +static int createCombinedFunctionIndex(StringRef Command) { + LLVMContext Context; + FunctionInfoIndex CombinedIndex; + uint64_t NextModuleId = 0; + for (auto &Filename : InputFilenames) { + std::string Error; + std::unique_ptr<FunctionInfoIndex> Index = + getFunctionIndexForFile(Filename, Error, Context); + if (!Index) { + errs() << Command << ": error loading file '" << Filename + << "': " << Error << "\n"; + return 1; + } + CombinedIndex.mergeFrom(std::move(Index), ++NextModuleId); + } + std::error_code EC; + assert(!OutputFilename.empty()); + raw_fd_ostream OS(OutputFilename + ".thinlto.bc", EC, + sys::fs::OpenFlags::F_None); + if (EC) { + errs() << Command << ": error opening the file '" << OutputFilename + << ".thinlto.bc': " << EC.message() << "\n"; + return 1; + } + WriteFunctionSummaryToFile(&CombinedIndex, OS); + OS.close(); + return 0; +} + int main(int argc, char **argv) { // Print a stack trace if we signal out. sys::PrintStackTraceOnErrorSignal(); @@ -176,6 +238,8 @@ int main(int argc, char **argv) { if (ListSymbolsOnly) return listSymbols(argv[0], Options); + if (ThinLTO) return createCombinedFunctionIndex(argv[0]); + unsigned BaseArg = 0; LTOCodeGenerator CodeGen;