Index: ELF/LTO.h =================================================================== --- ELF/LTO.h +++ ELF/LTO.h @@ -37,7 +37,7 @@ class BitcodeCompiler { public: void add(BitcodeFile &F); - std::unique_ptr compile(); + std::vector> compile(); BitcodeCompiler() : Combined(new llvm::Module("ld-temp.o", Context)), Mover(*Combined) {} @@ -48,7 +48,7 @@ llvm::LLVMContext Context; std::unique_ptr Combined; llvm::IRMover Mover; - SmallString<0> OwningData; + std::vector> OwningData; std::unique_ptr MB; llvm::StringSet<> InternalizedSyms; }; Index: ELF/LTO.cpp =================================================================== --- ELF/LTO.cpp +++ ELF/LTO.cpp @@ -16,6 +16,7 @@ #include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/Bitcode/ReaderWriter.h" #include "llvm/CodeGen/CommandFlags.h" +#include "llvm/CodeGen/ParallelCG.h" #include "llvm/IR/LegacyPassManager.h" #include "llvm/Linker/IRMover.h" #include "llvm/Support/StringSaver.h" @@ -136,9 +137,17 @@ GV.setLinkage(GlobalValue::InternalLinkage); } +static SubtargetFeatures getFeatures(Triple &TheTriple) { + SubtargetFeatures Features; + Features.getDefaultSubtargetFeatures(TheTriple); + for (const std::string &A : MAttrs) + Features.AddFeature(A); + return Features; +} + // Merge all the bitcode files we have seen, codegen the result // and return the resulting ObjectFile. -std::unique_ptr BitcodeCompiler::compile() { +std::vector> BitcodeCompiler::compile() { for (const auto &Name : InternalizedSyms) { GlobalValue *GV = Combined->getNamedValue(Name.first()); assert(GV); @@ -151,17 +160,40 @@ std::unique_ptr TM(getTargetMachine()); runLTOPasses(*Combined, *TM); - raw_svector_ostream OS(OwningData); - legacy::PassManager CodeGenPasses; - if (TM->addPassesToEmitFile(CodeGenPasses, OS, - TargetMachine::CGFT_ObjectFile)) - fatal("failed to setup codegen"); - CodeGenPasses.run(*Combined); - MB = MemoryBuffer::getMemBuffer(OwningData, - "LLD-INTERNAL-combined-lto-object", false); + // XXXdcci: make this a tunable. + OwningData.resize(4); + + std::list OSs; + std::vector OSPtrs; + for (SmallString<0> &Obj: OwningData) { + OSs.emplace_back(Obj); + OSPtrs.push_back(&OSs.back()); + } + + // BEGIN SHAME. + const std::string &TripleStr = Combined->getTargetTriple(); + std::string MCpu; + Triple TheTriple(TripleStr); + SubtargetFeatures Features = getFeatures(TheTriple); + TargetOptions Options = InitTargetOptionsFromCodeGenFlags(); + Reloc::Model R = Config->Pic ? Reloc::PIC_ : Reloc::Static; + CodeGenOpt::Level CGOptLevel = CodeGenOpt::Default; + + splitCodeGen(std::move(Combined), OSPtrs, {}, MCpu, Features.getString(), + Options, R, CodeModel::Default, CGOptLevel); + + std::vector> ObjFiles; + for (SmallString<0> &Obj: OwningData) { + ObjFiles.push_back( + createObjectFile(MemoryBufferRef(StringRef(Obj.data(), Obj.size()), + "LLD-INTERNAL-combined-lto-object"))); + } + +#if 0 if (Config->SaveTemps) saveLtoObjectFile(MB->getBuffer()); - return createObjectFile(*MB); +#endif + return ObjFiles; } TargetMachine *BitcodeCompiler::getTargetMachine() { Index: ELF/SymbolTable.cpp =================================================================== --- ELF/SymbolTable.cpp +++ ELF/SymbolTable.cpp @@ -110,24 +110,26 @@ Lto.reset(new BitcodeCompiler); for (const std::unique_ptr &F : BitcodeFiles) Lto->add(*F); - std::unique_ptr IF = Lto->compile(); - ObjectFile *Obj = cast>(IF.release()); - - // Replace bitcode symbols. - llvm::DenseSet DummyGroups; - Obj->parse(DummyGroups); - for (SymbolBody *Body : Obj->getNonLocalSymbols()) { - Symbol *Sym = insert(Body); - Sym->Body->setUsedInRegularObj(); - if (Sym->Body->isShared()) - Sym->Body->MustBeInDynSym = true; - if (Sym->Body->MustBeInDynSym) - Body->MustBeInDynSym = true; - if (!Sym->Body->isUndefined() && Body->isUndefined()) - continue; - Sym->Body = Body; + std::vector> IFs = Lto->compile(); + for (auto &IF : IFs) { + ObjectFile *Obj = cast>(IF.release()); + + // Replace bitcode symbols. + llvm::DenseSet DummyGroups; + Obj->parse(DummyGroups); + for (SymbolBody *Body : Obj->getNonLocalSymbols()) { + Symbol *Sym = insert(Body); + Sym->Body->setUsedInRegularObj(); + if (Sym->Body->isShared()) + Sym->Body->MustBeInDynSym = true; + if (Sym->Body->MustBeInDynSym) + Body->MustBeInDynSym = true; + if (!Sym->Body->isUndefined() && Body->isUndefined()) + continue; + Sym->Body = Body; + } + ObjectFiles.emplace_back(Obj); } - ObjectFiles.emplace_back(Obj); } // Add an undefined symbol.