Index: llvm/include/llvm/LTO/LTO.h =================================================================== --- llvm/include/llvm/LTO/LTO.h +++ llvm/include/llvm/LTO/LTO.h @@ -279,9 +279,9 @@ unsigned ParallelCodeGenParallelismLevel; LTOLLVMContext Ctx; - bool HasModule = false; - std::unique_ptr CombinedModule; - std::unique_ptr Mover; + bool HasCombinedModule = false; + Module CombinedModule; + IRMover Mover; // This stores the information about a regular LTO module that we have added // to the link. It will either be linked immediately (for modules without Index: llvm/include/llvm/LTO/LTOBackend.h =================================================================== --- llvm/include/llvm/LTO/LTOBackend.h +++ llvm/include/llvm/LTO/LTOBackend.h @@ -37,8 +37,8 @@ /// Runs a regular LTO backend. The regular LTO backend can also act as the /// regular LTO phase of ThinLTO, which may need to access the combined index. Error backend(Config &C, AddStreamFn AddStream, - unsigned ParallelCodeGenParallelismLevel, - std::unique_ptr M, ModuleSummaryIndex &CombinedIndex); + unsigned ParallelCodeGenParallelismLevel, Module &M, + ModuleSummaryIndex &CombinedIndex); /// Runs a ThinLTO backend. Error thinBackend(Config &C, unsigned Task, AddStreamFn AddStream, Module &M, Index: llvm/include/llvm/Transforms/Utils/SplitModule.h =================================================================== --- llvm/include/llvm/Transforms/Utils/SplitModule.h +++ llvm/include/llvm/Transforms/Utils/SplitModule.h @@ -34,7 +34,7 @@ /// - Internal symbols defined in module-level inline asm should be visible to /// each partition. void SplitModule( - std::unique_ptr M, unsigned N, + Module &M, unsigned N, function_ref MPart)> ModuleCallback, bool PreserveLocals = false); Index: llvm/lib/CodeGen/ParallelCG.cpp =================================================================== --- llvm/lib/CodeGen/ParallelCG.cpp +++ llvm/lib/CodeGen/ParallelCG.cpp @@ -56,7 +56,7 @@ int ThreadCount = 0; SplitModule( - std::move(M), OSs.size(), + *M, OSs.size(), [&](std::unique_ptr MPart) { // We want to clone the module in a new context to multi-thread the // codegen. We do it by serializing partition modules to bitcode Index: llvm/lib/LTO/LTO.cpp =================================================================== --- llvm/lib/LTO/LTO.cpp +++ llvm/lib/LTO/LTO.cpp @@ -385,7 +385,7 @@ LTO::RegularLTOState::RegularLTOState(unsigned ParallelCodeGenParallelismLevel, Config &Conf) : ParallelCodeGenParallelismLevel(ParallelCodeGenParallelismLevel), - Ctx(Conf) {} + Ctx(Conf), CombinedModule("ld-temp.o", Ctx), Mover(CombinedModule) {} LTO::ThinLTOState::ThinLTOState(ThinBackend Backend) : Backend(Backend) { if (!Backend) @@ -656,12 +656,7 @@ Error LTO::linkRegularLTO(RegularLTOState::AddedModule Mod, bool LivenessFromIndex) { - if (!RegularLTO.CombinedModule) { - RegularLTO.CombinedModule = - llvm::make_unique("ld-temp.o", RegularLTO.Ctx); - RegularLTO.Mover = llvm::make_unique(*RegularLTO.CombinedModule); - } - + RegularLTO.HasCombinedModule = true; std::vector Keep; for (GlobalValue *GV : Mod.Keep) { if (LivenessFromIndex && !ThinLTO.CombinedIndex.isGUIDLive(GV->getGUID())) @@ -675,16 +670,16 @@ // Only link available_externally definitions if we don't already have a // definition. GlobalValue *CombinedGV = - RegularLTO.CombinedModule->getNamedValue(GV->getName()); + RegularLTO.CombinedModule.getNamedValue(GV->getName()); if (CombinedGV && !CombinedGV->isDeclaration()) continue; Keep.push_back(GV); } - return RegularLTO.Mover->move(std::move(Mod.M), Keep, - [](GlobalValue &, IRMover::ValueAdder) {}, - /* IsPerformingImport */ false); + return RegularLTO.Mover.move(std::move(Mod.M), Keep, + [](GlobalValue &, IRMover::ValueAdder) {}, + /* IsPerformingImport */ false); } // Add a ThinLTO module to the link. @@ -757,8 +752,8 @@ // Save the status of having a regularLTO combined module, as // this is needed for generating the ThinLTO Task ID, and // the CombinedModule will be moved at the end of runRegularLTO. - bool HasRegularLTO = RegularLTO.CombinedModule != nullptr || - !RegularLTO.ModsWithSummaries.empty(); + bool HasRegularLTO = + RegularLTO.HasCombinedModule || !RegularLTO.ModsWithSummaries.empty(); // Invoke regular LTO if there was a regular LTO module to start with. if (HasRegularLTO) if (auto E = runRegularLTO(AddStream)) @@ -774,12 +769,12 @@ // Make sure commons have the right size/alignment: we kept the largest from // all the prevailing when adding the inputs, and we apply it here. - const DataLayout &DL = RegularLTO.CombinedModule->getDataLayout(); + const DataLayout &DL = RegularLTO.CombinedModule.getDataLayout(); for (auto &I : RegularLTO.Commons) { if (!I.second.Prevailing) // Don't do anything if no instance of this common was prevailing. continue; - GlobalVariable *OldGV = RegularLTO.CombinedModule->getNamedGlobal(I.first); + GlobalVariable *OldGV = RegularLTO.CombinedModule.getNamedGlobal(I.first); if (OldGV && DL.getTypeAllocSize(OldGV->getValueType()) == I.second.Size) { // Don't create a new global if the type is already correct, just make // sure the alignment is correct. @@ -788,7 +783,7 @@ } ArrayType *Ty = ArrayType::get(Type::getInt8Ty(RegularLTO.Ctx), I.second.Size); - auto *GV = new GlobalVariable(*RegularLTO.CombinedModule, Ty, false, + auto *GV = new GlobalVariable(RegularLTO.CombinedModule, Ty, false, GlobalValue::CommonLinkage, ConstantAggregateZero::get(Ty), ""); GV->setAlignment(I.second.Align); @@ -802,7 +797,7 @@ } if (Conf.PreOptModuleHook && - !Conf.PreOptModuleHook(0, *RegularLTO.CombinedModule)) + !Conf.PreOptModuleHook(0, RegularLTO.CombinedModule)) return Error::success(); if (!Conf.CodeGenOnly) { @@ -814,7 +809,7 @@ continue; GlobalValue *GV = - RegularLTO.CombinedModule->getNamedValue(R.second.IRName); + RegularLTO.CombinedModule.getNamedValue(R.second.IRName); // Ignore symbols defined in other partitions. if (!GV || GV->hasLocalLinkage()) continue; @@ -825,11 +820,11 @@ } if (Conf.PostInternalizeModuleHook && - !Conf.PostInternalizeModuleHook(0, *RegularLTO.CombinedModule)) + !Conf.PostInternalizeModuleHook(0, RegularLTO.CombinedModule)) return Error::success(); } return backend(Conf, AddStream, RegularLTO.ParallelCodeGenParallelismLevel, - std::move(RegularLTO.CombinedModule), ThinLTO.CombinedIndex); + RegularLTO.CombinedModule, ThinLTO.CombinedIndex); } /// This class defines the interface to the ThinLTO backend. Index: llvm/lib/LTO/LTOBackend.cpp =================================================================== --- llvm/lib/LTO/LTOBackend.cpp +++ llvm/lib/LTO/LTOBackend.cpp @@ -286,14 +286,13 @@ } void splitCodeGen(Config &C, TargetMachine *TM, AddStreamFn AddStream, - unsigned ParallelCodeGenParallelismLevel, - std::unique_ptr Mod) { + unsigned ParallelCodeGenParallelismLevel, Module &Mod) { ThreadPool CodegenThreadPool(ParallelCodeGenParallelismLevel); unsigned ThreadCount = 0; const Target *T = &TM->getTarget(); SplitModule( - std::move(Mod), ParallelCodeGenParallelismLevel, + Mod, ParallelCodeGenParallelismLevel, [&](std::unique_ptr MPart) { // We want to clone the module in a new context to multi-thread the // codegen. We do it by serializing partition modules to bitcode @@ -359,24 +358,23 @@ } Error lto::backend(Config &C, AddStreamFn AddStream, - unsigned ParallelCodeGenParallelismLevel, - std::unique_ptr Mod, + unsigned ParallelCodeGenParallelismLevel, Module &Mod, ModuleSummaryIndex &CombinedIndex) { - Expected TOrErr = initAndLookupTarget(C, *Mod); + Expected TOrErr = initAndLookupTarget(C, Mod); if (!TOrErr) return TOrErr.takeError(); - std::unique_ptr TM = createTargetMachine(C, *TOrErr, *Mod); + std::unique_ptr TM = createTargetMachine(C, *TOrErr, Mod); // Setup optimization remarks. auto DiagFileOrErr = lto::setupOptimizationRemarks( - Mod->getContext(), C.RemarksFilename, C.RemarksWithHotness); + Mod.getContext(), C.RemarksFilename, C.RemarksWithHotness); if (!DiagFileOrErr) return DiagFileOrErr.takeError(); auto DiagnosticOutputFile = std::move(*DiagFileOrErr); if (!C.CodeGenOnly) { - if (!opt(C, TM.get(), 0, *Mod, /*IsThinLTO=*/false, + if (!opt(C, TM.get(), 0, Mod, /*IsThinLTO=*/false, /*ExportSummary=*/&CombinedIndex, /*ImportSummary=*/nullptr)) { finalizeOptimizationRemarks(std::move(DiagnosticOutputFile)); return Error::success(); @@ -384,10 +382,9 @@ } if (ParallelCodeGenParallelismLevel == 1) { - codegen(C, TM.get(), AddStream, 0, *Mod); + codegen(C, TM.get(), AddStream, 0, Mod); } else { - splitCodeGen(C, TM.get(), AddStream, ParallelCodeGenParallelismLevel, - std::move(Mod)); + splitCodeGen(C, TM.get(), AddStream, ParallelCodeGenParallelismLevel, Mod); } finalizeOptimizationRemarks(std::move(DiagnosticOutputFile)); return Error::success(); Index: llvm/lib/Transforms/Utils/SplitModule.cpp =================================================================== --- llvm/lib/Transforms/Utils/SplitModule.cpp +++ llvm/lib/Transforms/Utils/SplitModule.cpp @@ -141,15 +141,15 @@ } if (GV.hasLocalLinkage()) - addAllGlobalValueUsers(GVtoClusterMap, &GV, &GV); - }; - - llvm::for_each(M->functions(), recordGVSet); - llvm::for_each(M->globals(), recordGVSet); - llvm::for_each(M->aliases(), recordGVSet); - - // Assigned all GVs to merged clusters while balancing number of objects in - // each. + addAllGlobalValueUsers(GVtoClusterMap, &GV, &GV); + }; + + llvm::for_each(M->functions(), recordGVSet); + llvm::for_each(M->globals(), recordGVSet); + llvm::for_each(M->aliases(), recordGVSet); + + // Assigned all GVs to merged clusters while balancing number of objects in + // each. auto CompareClusters = [](const std::pair &a, const std::pair &b) { if (a.second || b.second) @@ -246,31 +246,31 @@ } void llvm::SplitModule( - std::unique_ptr M, unsigned N, + Module &M, unsigned N, function_ref MPart)> ModuleCallback, bool PreserveLocals) { if (!PreserveLocals) { - for (Function &F : *M) + for (Function &F : M) externalize(&F); - for (GlobalVariable &GV : M->globals()) + for (GlobalVariable &GV : M.globals()) externalize(&GV); - for (GlobalAlias &GA : M->aliases()) + for (GlobalAlias &GA : M.aliases()) externalize(&GA); - for (GlobalIFunc &GIF : M->ifuncs()) + for (GlobalIFunc &GIF : M.ifuncs()) externalize(&GIF); } // This performs splitting without a need for externalization, which might not // always be possible. ClusterIDMapType ClusterIDMap; - findPartitions(M.get(), ClusterIDMap, N); + findPartitions(&M, ClusterIDMap, N); // FIXME: We should be able to reuse M as the last partition instead of // cloning it. for (unsigned I = 0; I < N; ++I) { ValueToValueMapTy VMap; std::unique_ptr MPart( - CloneModule(M.get(), VMap, [&](const GlobalValue *GV) { + CloneModule(&M, VMap, [&](const GlobalValue *GV) { if (ClusterIDMap.count(GV)) return (ClusterIDMap[GV] == I); else Index: llvm/tools/llvm-split/llvm-split.cpp =================================================================== --- llvm/tools/llvm-split/llvm-split.cpp +++ llvm/tools/llvm-split/llvm-split.cpp @@ -53,7 +53,7 @@ } unsigned I = 0; - SplitModule(std::move(M), NumOutputs, [&](std::unique_ptr MPart) { + SplitModule(*M, NumOutputs, [&](std::unique_ptr MPart) { std::error_code EC; std::unique_ptr Out( new ToolOutputFile(OutputFilename + utostr(I++), EC, sys::fs::F_None));