Loading llvm/include/llvm/LTO/LTOBackend.h +3 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,9 @@ Error thinBackend(const Config &C, unsigned Task, AddStreamFn AddStream, const FunctionImporter::ImportMapTy &ImportList, const GVSummaryMapTy &DefinedGlobals, MapVector<StringRef, BitcodeModule> &ModuleMap); Error finalizeOptimizationRemarks( std::unique_ptr<ToolOutputFile> DiagOutputFile); } } Loading llvm/lib/IR/DiagnosticInfo.cpp +3 −6 Original line number Diff line number Diff line Loading @@ -244,11 +244,8 @@ OptimizationRemark::OptimizationRemark(const char *PassName, RemarkName, *Inst->getParent()->getParent(), Inst->getDebugLoc(), Inst->getParent()) {} // Helper to allow for an assert before attempting to return an invalid // reference. static const BasicBlock &getFirstFunctionBlock(const Function *Func) { assert(!Func->empty() && "Function does not have a body"); return Func->front(); static const BasicBlock *getFirstFunctionBlock(const Function *Func) { return Func->empty() ? nullptr : &Func->front(); } OptimizationRemark::OptimizationRemark(const char *PassName, Loading @@ -256,7 +253,7 @@ OptimizationRemark::OptimizationRemark(const char *PassName, const Function *Func) : DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName, RemarkName, *Func, Func->getSubprogram(), &getFirstFunctionBlock(Func)) {} getFirstFunctionBlock(Func)) {} bool OptimizationRemark::isEnabled() const { const Function &Fn = getFunction(); Loading llvm/lib/LTO/LTO.cpp +36 −14 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ #include "llvm/LTO/LTO.h" #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/OptimizationRemarkEmitter.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/Bitcode/BitcodeReader.h" Loading Loading @@ -781,8 +782,15 @@ Error LTO::linkRegularLTO(RegularLTOState::AddedModule Mod, bool LivenessFromIndex) { std::vector<GlobalValue *> Keep; for (GlobalValue *GV : Mod.Keep) { if (LivenessFromIndex && !ThinLTO.CombinedIndex.isGUIDLive(GV->getGUID())) if (LivenessFromIndex && !ThinLTO.CombinedIndex.isGUIDLive(GV->getGUID())) { if (Function *F = dyn_cast<Function>(GV)) { OptimizationRemarkEmitter ORE(F); ORE.emit(OptimizationRemark(DEBUG_TYPE, "deadfunction", F) << ore::NV("Function", F) << " not added to the combined module "); } continue; } if (!GV->hasAvailableExternallyLinkage()) { Keep.push_back(GV); Loading Loading @@ -931,17 +939,6 @@ Error LTO::run(AddStreamFn AddStream, NativeObjectCache Cache) { return StatsFileOrErr.takeError(); std::unique_ptr<ToolOutputFile> StatsFile = std::move(StatsFileOrErr.get()); // Finalize linking of regular LTO modules containing summaries now that // we have computed liveness information. for (auto &M : RegularLTO.ModsWithSummaries) if (Error Err = linkRegularLTO(std::move(M), /*LivenessFromIndex=*/true)) return Err; // Ensure we don't have inconsistently split LTO units with type tests. if (Error Err = checkPartiallySplit()) return Err; Error Result = runRegularLTO(AddStream); if (!Result) Result = runThinLTO(AddStream, Cache, GUIDPreservedSymbols); Loading @@ -953,6 +950,27 @@ Error LTO::run(AddStreamFn AddStream, NativeObjectCache Cache) { } Error LTO::runRegularLTO(AddStreamFn AddStream) { // Setup optimization remarks. auto DiagFileOrErr = lto::setupOptimizationRemarks( RegularLTO.CombinedModule->getContext(), Conf.RemarksFilename, Conf.RemarksPasses, Conf.RemarksFormat, Conf.RemarksWithHotness); if (!DiagFileOrErr) return DiagFileOrErr.takeError(); // Finalize linking of regular LTO modules containing summaries now that // we have computed liveness information. for (auto &M : RegularLTO.ModsWithSummaries) if (Error Err = linkRegularLTO(std::move(M), /*LivenessFromIndex=*/true)) return Err; // Ensure we don't have inconsistently split LTO units with type tests. // FIXME: this checks both LTO and ThinLTO. It happens to work as we take // this path both cases but eventually this should be split into two and // do the ThinLTO checks in `runThinLTO`. if (Error Err = checkPartiallySplit()) return Err; // 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(); Loading Loading @@ -1017,8 +1035,12 @@ Error LTO::runRegularLTO(AddStreamFn AddStream) { !Conf.PostInternalizeModuleHook(0, *RegularLTO.CombinedModule)) return Error::success(); } return backend(Conf, AddStream, RegularLTO.ParallelCodeGenParallelismLevel, std::move(RegularLTO.CombinedModule), ThinLTO.CombinedIndex); if (Error Err = backend(Conf, AddStream, RegularLTO.ParallelCodeGenParallelismLevel, std::move(RegularLTO.CombinedModule), ThinLTO.CombinedIndex)) return Err; return finalizeOptimizationRemarks(std::move(*DiagFileOrErr)); } static const char *libcallRoutineNames[] = { Loading llvm/lib/LTO/LTOBackend.cpp +4 −12 Original line number Diff line number Diff line Loading @@ -434,8 +434,8 @@ Expected<const Target *> initAndLookupTarget(const Config &C, Module &Mod) { } } static Error finalizeOptimizationRemarks(std::unique_ptr<ToolOutputFile> DiagOutputFile) { Error lto::finalizeOptimizationRemarks( std::unique_ptr<ToolOutputFile> DiagOutputFile) { // Make sure we flush the diagnostic remarks file in case the linker doesn't // call the global destructors before exiting. if (!DiagOutputFile) Loading @@ -455,18 +455,10 @@ Error lto::backend(const Config &C, AddStreamFn AddStream, std::unique_ptr<TargetMachine> TM = createTargetMachine(C, *TOrErr, *Mod); // Setup optimization remarks. auto DiagFileOrErr = lto::setupOptimizationRemarks( Mod->getContext(), C.RemarksFilename, C.RemarksPasses, C.RemarksFormat, C.RemarksWithHotness); if (!DiagFileOrErr) return DiagFileOrErr.takeError(); auto DiagnosticOutputFile = std::move(*DiagFileOrErr); if (!C.CodeGenOnly) { if (!opt(C, TM.get(), 0, *Mod, /*IsThinLTO=*/false, /*ExportSummary=*/&CombinedIndex, /*ImportSummary=*/nullptr)) return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile)); return Error::success(); } if (ParallelCodeGenParallelismLevel == 1) { Loading @@ -475,7 +467,7 @@ Error lto::backend(const Config &C, AddStreamFn AddStream, splitCodeGen(C, TM.get(), AddStream, ParallelCodeGenParallelismLevel, std::move(Mod)); } return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile)); return Error::success(); } static void dropDeadSymbols(Module &Mod, const GVSummaryMapTy &DefinedGlobals, Loading llvm/test/LTO/Resolution/X86/dead-strip-fulllto.ll +13 −3 Original line number Diff line number Diff line ; RUN: opt -module-summary -o %t %s ; RUN: opt -module-summary -o %t2 %S/Inputs/dead-strip-fulllto.ll ; RUN: llvm-lto2 run %t -r %t,main,px -r %t,live1, -r %t,live2,p -r %t,dead2,p \ ; RUN: llvm-lto2 run --pass-remarks-output=%t4.yaml --pass-remarks-filter=. \ ; RUN: %t -r %t,main,px -r %t,live1, -r %t,live2,p -r %t,dead2,p \ ; RUN: %t2 -r %t2,live1,p -r %t2,live2, -r %t2,dead1,p -r %t2,dead2, -r %t2,odr, \ ; RUN: -save-temps -o %t3 ; RUN: cat %t4.yaml | FileCheck %s -check-prefix=REMARK ; RUN: llvm-nm %t3.0 | FileCheck --check-prefix=FULL %s ; RUN: llvm-nm %t3.1 | FileCheck --check-prefix=THIN %s Loading @@ -13,6 +16,13 @@ ; RUN: llvm-nm %t3.0 | FileCheck --check-prefix=FULL %s ; RUN: llvm-nm %t3.1 | FileCheck --check-prefix=THIN %s ; REMARK: Pass: lto ; REMARK-NEXT: Name: deadfunction ; REMARK-NEXT: Function: dead2 ; REMARK-NEXT: Args: ; REMARK-NEXT: - Function: dead2 ; REMARK-NEXT: - String: ' not added to the combined module ' ; FULL-NOT: dead ; FULL: U live1 ; FULL: T live2 Loading Loading
llvm/include/llvm/LTO/LTOBackend.h +3 −0 Original line number Diff line number Diff line Loading @@ -45,6 +45,9 @@ Error thinBackend(const Config &C, unsigned Task, AddStreamFn AddStream, const FunctionImporter::ImportMapTy &ImportList, const GVSummaryMapTy &DefinedGlobals, MapVector<StringRef, BitcodeModule> &ModuleMap); Error finalizeOptimizationRemarks( std::unique_ptr<ToolOutputFile> DiagOutputFile); } } Loading
llvm/lib/IR/DiagnosticInfo.cpp +3 −6 Original line number Diff line number Diff line Loading @@ -244,11 +244,8 @@ OptimizationRemark::OptimizationRemark(const char *PassName, RemarkName, *Inst->getParent()->getParent(), Inst->getDebugLoc(), Inst->getParent()) {} // Helper to allow for an assert before attempting to return an invalid // reference. static const BasicBlock &getFirstFunctionBlock(const Function *Func) { assert(!Func->empty() && "Function does not have a body"); return Func->front(); static const BasicBlock *getFirstFunctionBlock(const Function *Func) { return Func->empty() ? nullptr : &Func->front(); } OptimizationRemark::OptimizationRemark(const char *PassName, Loading @@ -256,7 +253,7 @@ OptimizationRemark::OptimizationRemark(const char *PassName, const Function *Func) : DiagnosticInfoIROptimization(DK_OptimizationRemark, DS_Remark, PassName, RemarkName, *Func, Func->getSubprogram(), &getFirstFunctionBlock(Func)) {} getFirstFunctionBlock(Func)) {} bool OptimizationRemark::isEnabled() const { const Function &Fn = getFunction(); Loading
llvm/lib/LTO/LTO.cpp +36 −14 Original line number Diff line number Diff line Loading @@ -12,6 +12,7 @@ #include "llvm/LTO/LTO.h" #include "llvm/ADT/Statistic.h" #include "llvm/Analysis/OptimizationRemarkEmitter.h" #include "llvm/Analysis/TargetLibraryInfo.h" #include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/Bitcode/BitcodeReader.h" Loading Loading @@ -781,8 +782,15 @@ Error LTO::linkRegularLTO(RegularLTOState::AddedModule Mod, bool LivenessFromIndex) { std::vector<GlobalValue *> Keep; for (GlobalValue *GV : Mod.Keep) { if (LivenessFromIndex && !ThinLTO.CombinedIndex.isGUIDLive(GV->getGUID())) if (LivenessFromIndex && !ThinLTO.CombinedIndex.isGUIDLive(GV->getGUID())) { if (Function *F = dyn_cast<Function>(GV)) { OptimizationRemarkEmitter ORE(F); ORE.emit(OptimizationRemark(DEBUG_TYPE, "deadfunction", F) << ore::NV("Function", F) << " not added to the combined module "); } continue; } if (!GV->hasAvailableExternallyLinkage()) { Keep.push_back(GV); Loading Loading @@ -931,17 +939,6 @@ Error LTO::run(AddStreamFn AddStream, NativeObjectCache Cache) { return StatsFileOrErr.takeError(); std::unique_ptr<ToolOutputFile> StatsFile = std::move(StatsFileOrErr.get()); // Finalize linking of regular LTO modules containing summaries now that // we have computed liveness information. for (auto &M : RegularLTO.ModsWithSummaries) if (Error Err = linkRegularLTO(std::move(M), /*LivenessFromIndex=*/true)) return Err; // Ensure we don't have inconsistently split LTO units with type tests. if (Error Err = checkPartiallySplit()) return Err; Error Result = runRegularLTO(AddStream); if (!Result) Result = runThinLTO(AddStream, Cache, GUIDPreservedSymbols); Loading @@ -953,6 +950,27 @@ Error LTO::run(AddStreamFn AddStream, NativeObjectCache Cache) { } Error LTO::runRegularLTO(AddStreamFn AddStream) { // Setup optimization remarks. auto DiagFileOrErr = lto::setupOptimizationRemarks( RegularLTO.CombinedModule->getContext(), Conf.RemarksFilename, Conf.RemarksPasses, Conf.RemarksFormat, Conf.RemarksWithHotness); if (!DiagFileOrErr) return DiagFileOrErr.takeError(); // Finalize linking of regular LTO modules containing summaries now that // we have computed liveness information. for (auto &M : RegularLTO.ModsWithSummaries) if (Error Err = linkRegularLTO(std::move(M), /*LivenessFromIndex=*/true)) return Err; // Ensure we don't have inconsistently split LTO units with type tests. // FIXME: this checks both LTO and ThinLTO. It happens to work as we take // this path both cases but eventually this should be split into two and // do the ThinLTO checks in `runThinLTO`. if (Error Err = checkPartiallySplit()) return Err; // 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(); Loading Loading @@ -1017,8 +1035,12 @@ Error LTO::runRegularLTO(AddStreamFn AddStream) { !Conf.PostInternalizeModuleHook(0, *RegularLTO.CombinedModule)) return Error::success(); } return backend(Conf, AddStream, RegularLTO.ParallelCodeGenParallelismLevel, std::move(RegularLTO.CombinedModule), ThinLTO.CombinedIndex); if (Error Err = backend(Conf, AddStream, RegularLTO.ParallelCodeGenParallelismLevel, std::move(RegularLTO.CombinedModule), ThinLTO.CombinedIndex)) return Err; return finalizeOptimizationRemarks(std::move(*DiagFileOrErr)); } static const char *libcallRoutineNames[] = { Loading
llvm/lib/LTO/LTOBackend.cpp +4 −12 Original line number Diff line number Diff line Loading @@ -434,8 +434,8 @@ Expected<const Target *> initAndLookupTarget(const Config &C, Module &Mod) { } } static Error finalizeOptimizationRemarks(std::unique_ptr<ToolOutputFile> DiagOutputFile) { Error lto::finalizeOptimizationRemarks( std::unique_ptr<ToolOutputFile> DiagOutputFile) { // Make sure we flush the diagnostic remarks file in case the linker doesn't // call the global destructors before exiting. if (!DiagOutputFile) Loading @@ -455,18 +455,10 @@ Error lto::backend(const Config &C, AddStreamFn AddStream, std::unique_ptr<TargetMachine> TM = createTargetMachine(C, *TOrErr, *Mod); // Setup optimization remarks. auto DiagFileOrErr = lto::setupOptimizationRemarks( Mod->getContext(), C.RemarksFilename, C.RemarksPasses, C.RemarksFormat, C.RemarksWithHotness); if (!DiagFileOrErr) return DiagFileOrErr.takeError(); auto DiagnosticOutputFile = std::move(*DiagFileOrErr); if (!C.CodeGenOnly) { if (!opt(C, TM.get(), 0, *Mod, /*IsThinLTO=*/false, /*ExportSummary=*/&CombinedIndex, /*ImportSummary=*/nullptr)) return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile)); return Error::success(); } if (ParallelCodeGenParallelismLevel == 1) { Loading @@ -475,7 +467,7 @@ Error lto::backend(const Config &C, AddStreamFn AddStream, splitCodeGen(C, TM.get(), AddStream, ParallelCodeGenParallelismLevel, std::move(Mod)); } return finalizeOptimizationRemarks(std::move(DiagnosticOutputFile)); return Error::success(); } static void dropDeadSymbols(Module &Mod, const GVSummaryMapTy &DefinedGlobals, Loading
llvm/test/LTO/Resolution/X86/dead-strip-fulllto.ll +13 −3 Original line number Diff line number Diff line ; RUN: opt -module-summary -o %t %s ; RUN: opt -module-summary -o %t2 %S/Inputs/dead-strip-fulllto.ll ; RUN: llvm-lto2 run %t -r %t,main,px -r %t,live1, -r %t,live2,p -r %t,dead2,p \ ; RUN: llvm-lto2 run --pass-remarks-output=%t4.yaml --pass-remarks-filter=. \ ; RUN: %t -r %t,main,px -r %t,live1, -r %t,live2,p -r %t,dead2,p \ ; RUN: %t2 -r %t2,live1,p -r %t2,live2, -r %t2,dead1,p -r %t2,dead2, -r %t2,odr, \ ; RUN: -save-temps -o %t3 ; RUN: cat %t4.yaml | FileCheck %s -check-prefix=REMARK ; RUN: llvm-nm %t3.0 | FileCheck --check-prefix=FULL %s ; RUN: llvm-nm %t3.1 | FileCheck --check-prefix=THIN %s Loading @@ -13,6 +16,13 @@ ; RUN: llvm-nm %t3.0 | FileCheck --check-prefix=FULL %s ; RUN: llvm-nm %t3.1 | FileCheck --check-prefix=THIN %s ; REMARK: Pass: lto ; REMARK-NEXT: Name: deadfunction ; REMARK-NEXT: Function: dead2 ; REMARK-NEXT: Args: ; REMARK-NEXT: - Function: dead2 ; REMARK-NEXT: - String: ' not added to the combined module ' ; FULL-NOT: dead ; FULL: U live1 ; FULL: T live2 Loading