-
Notifications
You must be signed in to change notification settings - Fork 15.4k
[LLD][COFF] Add more --time-trace tags for ThinLTO linking
#156471
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -119,6 +119,7 @@ | |
| #include "llvm/Support/ErrorHandling.h" | ||
| #include "llvm/Support/MathExtras.h" | ||
| #include "llvm/Support/ModRef.h" | ||
| #include "llvm/Support/TimeProfiler.h" | ||
| #include "llvm/Support/raw_ostream.h" | ||
| #include <algorithm> | ||
| #include <cassert> | ||
|
|
@@ -399,6 +400,7 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport { | |
| bool hasBrokenDebugInfo() const { return BrokenDebugInfo; } | ||
|
|
||
| bool verify(const Function &F) { | ||
| llvm::TimeTraceScope timeScope("Verifier"); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe this is enough; do you really need the "Dominator Tree Builder" and "Verifier visit' timers as well?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Removed! |
||
| assert(F.getParent() == &M && | ||
| "An instance of this class only works with a specific module!"); | ||
|
|
||
|
|
@@ -408,8 +410,10 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport { | |
| // out-of-date dominator tree and makes it significantly more complex to run | ||
| // this code outside of a pass manager. | ||
| // FIXME: It's really gross that we have to cast away constness here. | ||
| if (!F.empty()) | ||
| if (!F.empty()) { | ||
| llvm::TimeTraceScope domScope("Dominator Tree Builder"); | ||
| DT.recalculate(const_cast<Function &>(F)); | ||
| } | ||
|
|
||
| for (const BasicBlock &BB : F) { | ||
| if (!BB.empty() && BB.back().isTerminator()) | ||
|
|
@@ -431,7 +435,10 @@ class Verifier : public InstVisitor<Verifier>, VerifierSupport { | |
|
|
||
| Broken = false; | ||
| // FIXME: We strip const here because the inst visitor strips const. | ||
| visit(const_cast<Function &>(F)); | ||
| { | ||
| llvm::TimeTraceScope domScope("Verifier visit"); | ||
|
||
| visit(const_cast<Function &>(F)); | ||
| } | ||
| verifySiblingFuncletUnwinds(); | ||
|
|
||
| if (ConvergenceVerifyHelper.sawTokens()) | ||
|
|
@@ -2832,6 +2839,7 @@ static Instruction *getSuccPad(Instruction *Terminator) { | |
| } | ||
|
|
||
| void Verifier::verifySiblingFuncletUnwinds() { | ||
| llvm::TimeTraceScope domScope("Verifier verify sibling funclet unwinds"); | ||
| SmallPtrSet<Instruction *, 8> Visited; | ||
| SmallPtrSet<Instruction *, 8> Active; | ||
| for (const auto &Pair : SiblingFuncletInfo) { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -631,6 +631,7 @@ LTO::~LTO() = default; | |
| void LTO::addModuleToGlobalRes(ArrayRef<InputFile::Symbol> Syms, | ||
| ArrayRef<SymbolResolution> Res, | ||
| unsigned Partition, bool InSummary) { | ||
| llvm::TimeTraceScope importScope("LTO add module to global resolution"); | ||
| auto *ResI = Res.begin(); | ||
| auto *ResE = Res.end(); | ||
| (void)ResE; | ||
|
|
@@ -731,6 +732,7 @@ static void writeToResolutionFile(raw_ostream &OS, InputFile *Input, | |
|
|
||
| Error LTO::add(std::unique_ptr<InputFile> Input, | ||
| ArrayRef<SymbolResolution> Res) { | ||
| llvm::TimeTraceScope importScope("LTO add input", Input->getName()); | ||
| assert(!CalledGetMaxTasks); | ||
|
|
||
| if (Conf.ResolutionFile) | ||
|
|
@@ -756,6 +758,7 @@ Error LTO::add(std::unique_ptr<InputFile> Input, | |
| Expected<ArrayRef<SymbolResolution>> | ||
| LTO::addModule(InputFile &Input, ArrayRef<SymbolResolution> InputRes, | ||
| unsigned ModI, ArrayRef<SymbolResolution> Res) { | ||
| llvm::TimeTraceScope importScope("LTO add module", Input.getName()); | ||
| Expected<BitcodeLTOInfo> LTOInfo = Input.Mods[ModI].getLTOInfo(); | ||
| if (!LTOInfo) | ||
| return LTOInfo.takeError(); | ||
|
|
@@ -850,6 +853,7 @@ Expected< | |
| LTO::addRegularLTO(InputFile &Input, ArrayRef<SymbolResolution> InputRes, | ||
| BitcodeModule BM, ArrayRef<InputFile::Symbol> Syms, | ||
| ArrayRef<SymbolResolution> Res) { | ||
| llvm::TimeTraceScope importScope("LTO add regular LTO"); | ||
| RegularLTOState::AddedModule Mod; | ||
| Expected<std::unique_ptr<Module>> MOrErr = | ||
| BM.getLazyModule(RegularLTO.Ctx, /*ShouldLazyLoadMetadata*/ true, | ||
|
|
@@ -1024,6 +1028,7 @@ LTO::addRegularLTO(InputFile &Input, ArrayRef<SymbolResolution> InputRes, | |
|
|
||
| Error LTO::linkRegularLTO(RegularLTOState::AddedModule Mod, | ||
| bool LivenessFromIndex) { | ||
| llvm::TimeTraceScope importScope("LTO link regular LTO"); | ||
| std::vector<GlobalValue *> Keep; | ||
| for (GlobalValue *GV : Mod.Keep) { | ||
| if (LivenessFromIndex && !ThinLTO.CombinedIndex.isGUIDLive(GV->getGUID())) { | ||
|
|
@@ -1063,6 +1068,7 @@ Error LTO::linkRegularLTO(RegularLTOState::AddedModule Mod, | |
| Expected<ArrayRef<SymbolResolution>> | ||
| LTO::addThinLTO(BitcodeModule BM, ArrayRef<InputFile::Symbol> Syms, | ||
| ArrayRef<SymbolResolution> Res) { | ||
| llvm::TimeTraceScope importScope("LTO add thin LTO"); | ||
| ArrayRef<SymbolResolution> ResTmp = Res; | ||
| for (const InputFile::Symbol &Sym : Syms) { | ||
| assert(!ResTmp.empty()); | ||
|
|
@@ -1252,6 +1258,7 @@ Error LTO::run(AddStreamFn AddStream, FileCache Cache) { | |
|
|
||
| void lto::updateMemProfAttributes(Module &Mod, | ||
| const ModuleSummaryIndex &Index) { | ||
| llvm::TimeTraceScope importScope("LTO update memprof attributes"); | ||
| if (Index.withSupportsHotColdNew()) | ||
| return; | ||
|
|
||
|
|
@@ -1282,6 +1289,7 @@ void lto::updateMemProfAttributes(Module &Mod, | |
| } | ||
|
|
||
| Error LTO::runRegularLTO(AddStreamFn AddStream) { | ||
| llvm::TimeTraceScope timeScope("Run regular LTO"); | ||
| // Setup optimization remarks. | ||
| auto DiagFileOrErr = lto::setupLLVMOptimizationRemarks( | ||
| RegularLTO.CombinedModule->getContext(), Conf.RemarksFilename, | ||
|
|
@@ -1294,10 +1302,12 @@ Error LTO::runRegularLTO(AddStreamFn AddStream) { | |
|
|
||
| // 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; | ||
| { | ||
| llvm::TimeTraceScope timeScope("Link regular LTO"); | ||
| 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 | ||
|
|
@@ -1526,6 +1536,9 @@ class InProcessThinBackend : public CGThinBackend { | |
| const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR, | ||
| const GVSummaryMapTy &DefinedGlobals, | ||
| MapVector<StringRef, BitcodeModule> &ModuleMap) { | ||
| auto ModuleID = BM.getModuleIdentifier(); | ||
| llvm::TimeTraceScope timeScope("Run ThinLTO backend thread (in-process)", | ||
| ModuleID); | ||
| auto RunThinBackend = [&](AddStreamFn AddStream) { | ||
| LTOLLVMContext BackendContext(Conf); | ||
| Expected<std::unique_ptr<Module>> MOrErr = BM.parseModule(BackendContext); | ||
|
|
@@ -1536,9 +1549,6 @@ class InProcessThinBackend : public CGThinBackend { | |
| ImportList, DefinedGlobals, &ModuleMap, | ||
| Conf.CodeGenOnly); | ||
| }; | ||
|
|
||
| auto ModuleID = BM.getModuleIdentifier(); | ||
|
|
||
| if (ShouldEmitIndexFiles) { | ||
| if (auto E = emitFiles(ImportList, ModuleID, ModuleID.str())) | ||
| return E; | ||
|
|
@@ -1639,6 +1649,9 @@ class FirstRoundThinBackend : public InProcessThinBackend { | |
| const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR, | ||
| const GVSummaryMapTy &DefinedGlobals, | ||
| MapVector<StringRef, BitcodeModule> &ModuleMap) override { | ||
| auto ModuleID = BM.getModuleIdentifier(); | ||
| llvm::TimeTraceScope timeScope("Run ThinLTO backend thread (first round)", | ||
| ModuleID); | ||
| auto RunThinBackend = [&](AddStreamFn CGAddStream, | ||
| AddStreamFn IRAddStream) { | ||
| LTOLLVMContext BackendContext(Conf); | ||
|
|
@@ -1650,8 +1663,6 @@ class FirstRoundThinBackend : public InProcessThinBackend { | |
| ImportList, DefinedGlobals, &ModuleMap, | ||
| Conf.CodeGenOnly, IRAddStream); | ||
| }; | ||
|
|
||
| auto ModuleID = BM.getModuleIdentifier(); | ||
| // Like InProcessThinBackend, we produce index files as needed for | ||
| // FirstRoundThinBackend. However, these files are not generated for | ||
| // SecondRoundThinBackend. | ||
|
|
@@ -1735,6 +1746,9 @@ class SecondRoundThinBackend : public InProcessThinBackend { | |
| const std::map<GlobalValue::GUID, GlobalValue::LinkageTypes> &ResolvedODR, | ||
| const GVSummaryMapTy &DefinedGlobals, | ||
| MapVector<StringRef, BitcodeModule> &ModuleMap) override { | ||
| auto ModuleID = BM.getModuleIdentifier(); | ||
| llvm::TimeTraceScope timeScope("Run ThinLTO backend thread (second round)", | ||
| ModuleID); | ||
| auto RunThinBackend = [&](AddStreamFn AddStream) { | ||
| LTOLLVMContext BackendContext(Conf); | ||
| std::unique_ptr<Module> LoadedModule = | ||
|
|
@@ -1744,8 +1758,6 @@ class SecondRoundThinBackend : public InProcessThinBackend { | |
| ImportList, DefinedGlobals, &ModuleMap, | ||
| /*CodeGenOnly=*/true); | ||
| }; | ||
|
|
||
| auto ModuleID = BM.getModuleIdentifier(); | ||
| if (!Cache.isValid() || !CombinedIndex.modulePaths().count(ModuleID) || | ||
| all_of(CombinedIndex.getModuleHash(ModuleID), | ||
| [](uint32_t V) { return V == 0; })) | ||
|
|
@@ -1915,13 +1927,9 @@ ThinBackend lto::createWriteIndexesThinBackend( | |
|
|
||
| Error LTO::runThinLTO(AddStreamFn AddStream, FileCache Cache, | ||
| const DenseSet<GlobalValue::GUID> &GUIDPreservedSymbols) { | ||
| llvm::TimeTraceScope timeScope("Run ThinLTO"); | ||
| LLVM_DEBUG(dbgs() << "Running ThinLTO\n"); | ||
| ThinLTO.CombinedIndex.releaseTemporaryMemory(); | ||
| timeTraceProfilerBegin("ThinLink", StringRef("")); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. With this removed, we've lost the timer of just the index-based thin link. Why remove it?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Reverted this change, the |
||
| auto TimeTraceScopeExit = llvm::make_scope_exit([]() { | ||
| if (llvm::timeTraceProfilerEnabled()) | ||
| llvm::timeTraceProfilerEnd(); | ||
| }); | ||
| if (ThinLTO.ModuleMap.empty()) | ||
| return Error::success(); | ||
|
|
||
|
|
@@ -2069,11 +2077,6 @@ Error LTO::runThinLTO(AddStreamFn AddStream, FileCache Cache, | |
|
|
||
| generateParamAccessSummary(ThinLTO.CombinedIndex); | ||
|
|
||
| if (llvm::timeTraceProfilerEnabled()) | ||
| llvm::timeTraceProfilerEnd(); | ||
|
|
||
| TimeTraceScopeExit.release(); | ||
|
|
||
| auto &ModuleMap = | ||
| ThinLTO.ModulesToCompile ? *ThinLTO.ModulesToCompile : ThinLTO.ModuleMap; | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's already a "Compile bitcode" TimeTraceScope just above in the same scope. Is this needed too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I moved this scope at the begining of
BitcodeCompiler::compile()and removed the one at the top of this function.