Index: llvm/trunk/test/tools/llvm-lto/Inputs/thinlto.ll =================================================================== --- llvm/trunk/test/tools/llvm-lto/Inputs/thinlto.ll +++ llvm/trunk/test/tools/llvm-lto/Inputs/thinlto.ll @@ -0,0 +1,4 @@ +define void @g() { +entry: + ret void +} Index: llvm/trunk/test/tools/llvm-lto/thinlto.ll =================================================================== --- llvm/trunk/test/tools/llvm-lto/thinlto.ll +++ llvm/trunk/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: ThinLTO( + "thinlto", cl::init(false), + cl::desc("Only write combined global index for ThinLTO backends")); + static cl::list InputFilenames(cl::Positional, cl::OneOrMore, cl::desc("")); @@ -151,6 +158,61 @@ 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 getFunctionIndexForFile( + StringRef Path, std::string &Error, LLVMContext &Context) { + std::unique_ptr Buffer; + ErrorOr> BufferOrErr = + MemoryBuffer::getFile(Path); + if (std::error_code EC = BufferOrErr.getError()) { + Error = EC.message(); + return nullptr; + } + Buffer = std::move(BufferOrErr.get()); + ErrorOr> 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 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 @@ if (ListSymbolsOnly) return listSymbols(argv[0], Options); + if (ThinLTO) return createCombinedFunctionIndex(argv[0]); + unsigned BaseArg = 0; LTOCodeGenerator CodeGen;