Index: ELF/SymbolTable.cpp =================================================================== --- ELF/SymbolTable.cpp +++ ELF/SymbolTable.cpp @@ -18,12 +18,16 @@ #include "Config.h" #include "Error.h" #include "Symbols.h" +#include "llvm/Analysis/TargetLibraryInfo.h" +#include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/Bitcode/ReaderWriter.h" #include "llvm/IR/LegacyPassManager.h" #include "llvm/Linker/IRMover.h" #include "llvm/Support/StringSaver.h" #include "llvm/Support/TargetRegistry.h" #include "llvm/Target/TargetMachine.h" +#include "llvm/Transforms/IPO.h" +#include "llvm/Transforms/IPO/PassManagerBuilder.h" using namespace llvm; using namespace llvm::object; @@ -106,6 +110,15 @@ OS << Buffer; } +// This is for use when debugging LTO. +static void saveBCFile(Module &M, StringRef Suffix) { + std::error_code EC; + raw_fd_ostream OS(Config->OutputFile.str() + Suffix.str(), EC, + sys::fs::OpenFlags::F_None); + check(EC); + WriteBitcodeToFile(&M, OS, /* ShouldPreserveUseListOrder */ true); +} + // Codegen the module M and returns the resulting InputFile. template std::unique_ptr SymbolTable::codegen(Module &M) { @@ -126,6 +139,26 @@ std::unique_ptr TM( TheTarget->createTargetMachine(TripleStr, "", "", Options, R)); + // Run LTO passes. + // For now we just blatantly mimic the gold plugin in LLVM, running + // exactly the same passes. We might re-evaluate this in the future. + M.setDataLayout(TM->createDataLayout()); + legacy::PassManager ltoPasses; + ltoPasses.add(createTargetTransformInfoWrapperPass(TM->getTargetIRAnalysis())); + PassManagerBuilder PMB; + PMB.LibraryInfo = new TargetLibraryInfoImpl(Triple(TM->getTargetTriple())); + PMB.Inliner = createFunctionInliningPass(); + PMB.VerifyInput = true; + PMB.VerifyOutput = true; + PMB.LoopVectorize = true; + PMB.SLPVectorize = true; + PMB.OptLevel = 2; // FIXME: This should be an option. + PMB.populateLTOPassManager(ltoPasses); + ltoPasses.run(*&M); + + if (Config->SaveTemps) + saveBCFile(M, ".lto.opt.bc"); + raw_svector_ostream OS(OwningLTOData); legacy::PassManager CodeGenPasses; if (TM->addPassesToEmitFile(CodeGenPasses, OS, @@ -169,15 +202,6 @@ [](GlobalValue &, IRMover::ValueAdder) {}); } -// This is for use when debugging LTO. -static void saveBCFile(Module &M) { - std::error_code EC; - raw_fd_ostream OS(Config->OutputFile.str() + ".lto.bc", EC, - sys::fs::OpenFlags::F_None); - check(EC); - WriteBitcodeToFile(&M, OS, /* ShouldPreserveUseListOrder */ true); -} - // Merge all the bitcode files we have seen, codegen the result and return // the resulting ObjectFile. template @@ -188,7 +212,7 @@ for (const std::unique_ptr &F : BitcodeFiles) addBitcodeFile(Mover, *F, Context); if (Config->SaveTemps) - saveBCFile(Combined); + saveBCFile(Combined, ".lto.bc"); std::unique_ptr F = codegen(Combined); ObjectFiles.emplace_back(cast>(F.release())); return &*ObjectFiles.back(); Index: test/ELF/lto/ctors.ll =================================================================== --- test/ELF/lto/ctors.ll +++ test/ELF/lto/ctors.ll @@ -8,6 +8,7 @@ @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @ctor, i8* null }] define void @ctor() { + call void asm "nop", ""() ret void } Index: test/ELF/lto/ltopasses-basic.ll =================================================================== --- /dev/null +++ test/ELF/lto/ltopasses-basic.ll @@ -0,0 +1,16 @@ +; REQUIRES: x86 +; RUN: llvm-as %s -o %t.o +; RUN: ld.lld -m elf_x86_64 %t.o -o %t.so -shared +; RUN: llvm-readobj -sections %t.so | FileCheck %s + +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-unknown-linux-gnu" + +@llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] [{ i32, void ()*, i8* } { i32 65535, void ()* @ctor, i8* null }] +define void @ctor() { + ret void +} + +; The llvm.global_ctors is unused and therefore it can be stripped from +; the produced shared library. Ensure it doesn't appear in the final output. +; CHECK-NOT: Name: .ctors