diff --git a/llvm/include/llvm/IR/PassManager.h b/llvm/include/llvm/IR/PassManager.h --- a/llvm/include/llvm/IR/PassManager.h +++ b/llvm/include/llvm/IR/PassManager.h @@ -514,11 +514,7 @@ if (!PI.runBeforePass(*Pass, IR)) continue; - PreservedAnalyses PassPA; - { - TimeTraceScope TimeScope(Pass->name(), IR.getName()); - PassPA = Pass->run(IR, AM, ExtraArgs...); - } + PreservedAnalyses PassPA = Pass->run(IR, AM, ExtraArgs...); // Call onto PassInstrumentation's AfterPass callbacks immediately after // running the pass. diff --git a/llvm/include/llvm/IR/PassTimeProfiling.h b/llvm/include/llvm/IR/PassTimeProfiling.h new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/IR/PassTimeProfiling.h @@ -0,0 +1,54 @@ +//===- PassTimingInfo.h - pass execution timing -----------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +/// \file +/// +/// This header defines classes/functions to handle pass time profiling +/// information with interfaces for new manager. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_IR_PASSTIMEPROFILING_H +#define LLVM_IR_PASSTIMEPROFILING_H + +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/IR/PassInstrumentation.h" +#include "llvm/Support/TimeProfiler.h" +#include "llvm/Support/Timer.h" +#include +#include + +namespace llvm { + +class Pass; +class PassInstrumentationCallbacks; +class raw_ostream; + +/// This class implements --time-trace functionality for new pass manager. +/// It provides the pass-instrumentation callbacks that measure the pass +/// execution time. They collect time tracing info by TimeProfiler. +class TimeProfilingPassesHandler { + +public: + // We intend this to be unique per-compilation, thus no copies. + TimeProfilingPassesHandler(const TimeProfilingPassesHandler &) = delete; + void operator=(const TimeProfilingPassesHandler &) = delete; + + void registerCallbacks(PassInstrumentationCallbacks &PIC); + +private: + PassInstrumentationCallbacks *PIC; + // Implementation of pass instrumentation callbacks. + void runBeforePass(StringRef PassID, Any IR); + void runAfterPass(); +}; + +} // namespace llvm + +#endif diff --git a/llvm/include/llvm/Passes/StandardInstrumentations.h b/llvm/include/llvm/Passes/StandardInstrumentations.h --- a/llvm/include/llvm/Passes/StandardInstrumentations.h +++ b/llvm/include/llvm/Passes/StandardInstrumentations.h @@ -20,6 +20,7 @@ #include "llvm/ADT/StringRef.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/OptBisect.h" +#include "llvm/IR/PassTimeProfiling.h" #include "llvm/IR/PassTimingInfo.h" #include "llvm/IR/ValueHandle.h" #include "llvm/Support/CommandLine.h" @@ -505,6 +506,7 @@ PrintIRInstrumentation PrintIR; PrintPassInstrumentation PrintPass; TimePassesHandler TimePasses; + TimeProfilingPassesHandler TimeProfilingPasses; OptNoneInstrumentation OptNone; OptBisectInstrumentation OptBisect; PreservedCFGCheckerInstrumentation PreservedCFGChecker; diff --git a/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h b/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h --- a/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h +++ b/llvm/include/llvm/Transforms/Scalar/LoopPassManager.h @@ -392,11 +392,7 @@ if (!PI.runBeforePass(*Pass, L)) return None; - PreservedAnalyses PA; - { - TimeTraceScope TimeScope(Pass->name(), IR.getName()); - PA = Pass->run(IR, AM, AR, U); - } + PreservedAnalyses PA = Pass->run(IR, AM, AR, U); // do not pass deleted Loop into the instrumentation if (U.skipCurrentLoop()) diff --git a/llvm/lib/Analysis/CGSCCPassManager.cpp b/llvm/lib/Analysis/CGSCCPassManager.cpp --- a/llvm/lib/Analysis/CGSCCPassManager.cpp +++ b/llvm/lib/Analysis/CGSCCPassManager.cpp @@ -84,11 +84,7 @@ if (!PI.runBeforePass(*Pass, *C)) continue; - PreservedAnalyses PassPA; - { - TimeTraceScope TimeScope(Pass->name()); - PassPA = Pass->run(*C, AM, G, UR); - } + PreservedAnalyses PassPA = Pass->run(*C, AM, G, UR); if (UR.InvalidatedSCCs.count(C)) PI.runAfterPassInvalidated(*Pass, PassPA); @@ -277,11 +273,7 @@ if (!PI.runBeforePass(*Pass, *C)) continue; - PreservedAnalyses PassPA; - { - TimeTraceScope TimeScope(Pass->name()); - PassPA = Pass->run(*C, CGAM, CG, UR); - } + PreservedAnalyses PassPA = Pass->run(*C, CGAM, CG, UR); if (UR.InvalidatedSCCs.count(C)) PI.runAfterPassInvalidated(*Pass, PassPA); @@ -548,12 +540,7 @@ if (!PI.runBeforePass(*Pass, F)) continue; - PreservedAnalyses PassPA; - { - TimeTraceScope TimeScope(Pass->name()); - PassPA = Pass->run(F, FAM); - } - + PreservedAnalyses PassPA = Pass->run(F, FAM); PI.runAfterPass(*Pass, F, PassPA); // We know that the function pass couldn't have invalidated any other diff --git a/llvm/lib/IR/CMakeLists.txt b/llvm/lib/IR/CMakeLists.txt --- a/llvm/lib/IR/CMakeLists.txt +++ b/llvm/lib/IR/CMakeLists.txt @@ -47,6 +47,7 @@ PassInstrumentation.cpp PassManager.cpp PassRegistry.cpp + PassTimeProfiling.cpp PassTimingInfo.cpp PrintPasses.cpp ProfDataUtils.cpp diff --git a/llvm/lib/IR/PassManager.cpp b/llvm/lib/IR/PassManager.cpp --- a/llvm/lib/IR/PassManager.cpp +++ b/llvm/lib/IR/PassManager.cpp @@ -121,12 +121,7 @@ if (!PI.runBeforePass(*Pass, F)) continue; - PreservedAnalyses PassPA; - { - TimeTraceScope TimeScope(Pass->name(), F.getName()); - PassPA = Pass->run(F, FAM); - } - + PreservedAnalyses PassPA = Pass->run(F, FAM); PI.runAfterPass(*Pass, F, PassPA); // We know that the function pass couldn't have invalidated any other diff --git a/llvm/lib/IR/PassTimeProfiling.cpp b/llvm/lib/IR/PassTimeProfiling.cpp new file mode 100644 --- /dev/null +++ b/llvm/lib/IR/PassTimeProfiling.cpp @@ -0,0 +1,76 @@ +//===- PassTimeProfiling.cpp - LLVM Pass Time Profiling Implementation ----===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file implements the LLVM Pass Time Profiling for new pass managers. +// +// PassTimeProfiling Class - This class is used to calculate information about +// the amount of time each pass takes to execute. This only happens when +// -time-trace is enabled on the command line. +// +//===----------------------------------------------------------------------===// + +#include "llvm/IR/PassTimeProfiling.h" +#include "llvm/Analysis/LazyCallGraph.h" +#include "llvm/Analysis/LoopInfo.h" +#include "llvm/Analysis/LoopInfoImpl.h" +#include "llvm/IR/Function.h" +#include "llvm/IR/Module.h" +#include "llvm/IR/PassInstrumentation.h" + +namespace llvm { +void TimeProfilingPassesHandler::registerCallbacks( + PassInstrumentationCallbacks &PIC) { + this->PIC = &PIC; + PIC.registerBeforeNonSkippedPassCallback( + [this](StringRef P, Any IR) { this->runBeforePass(P, IR); }); + PIC.registerAfterPassCallback( + [this](StringRef P, Any IR, const PreservedAnalyses &) { + this->runAfterPass(); + }); + PIC.registerBeforeAnalysisCallback( + [this](StringRef P, Any IR) { this->runBeforePass(P, IR); }); + PIC.registerAfterAnalysisCallback( + [this](StringRef P, Any IR) { this->runAfterPass(); }); +} + +namespace { +std::string getIRName(Any IR) { + if (any_isa(IR)) + return "[module]"; + + if (any_isa(IR)) { + const Function *F = any_cast(IR); + return F->getName().str(); + } + + if (any_isa(IR)) { + const LazyCallGraph::SCC *C = any_cast(IR); + return C->getName(); + } + + if (any_isa(IR)) { + const Loop *L = any_cast(IR); + return L->getName().str(); + } + + llvm_unreachable("Unknown wrapped IR type"); +} +} // namespace + +void TimeProfilingPassesHandler::runBeforePass(StringRef PassID, Any IR) { + if (getTimeTraceProfilerInstance() != nullptr) { + timeTraceProfilerBegin(PassID, getIRName(IR)); + } +} + +void TimeProfilingPassesHandler::runAfterPass() { + if (getTimeTraceProfilerInstance() != nullptr) { + timeTraceProfilerEnd(); + } +} +} // namespace llvm diff --git a/llvm/lib/Passes/StandardInstrumentations.cpp b/llvm/lib/Passes/StandardInstrumentations.cpp --- a/llvm/lib/Passes/StandardInstrumentations.cpp +++ b/llvm/lib/Passes/StandardInstrumentations.cpp @@ -2066,6 +2066,7 @@ PrintIR.registerCallbacks(PIC); PrintPass.registerCallbacks(PIC); TimePasses.registerCallbacks(PIC); + TimeProfilingPasses.registerCallbacks(PIC); OptNone.registerCallbacks(PIC); OptBisect.registerCallbacks(PIC); if (FAM) diff --git a/llvm/lib/Transforms/Scalar/LoopPassManager.cpp b/llvm/lib/Transforms/Scalar/LoopPassManager.cpp --- a/llvm/lib/Transforms/Scalar/LoopPassManager.cpp +++ b/llvm/lib/Transforms/Scalar/LoopPassManager.cpp @@ -291,11 +291,7 @@ if (!PI.runBeforePass(*Pass, *L)) continue; - PreservedAnalyses PassPA; - { - TimeTraceScope TimeScope(Pass->name()); - PassPA = Pass->run(*L, LAM, LAR, Updater); - } + PreservedAnalyses PassPA = Pass->run(*L, LAM, LAR, Updater); // Do not pass deleted Loop into the instrumentation. if (Updater.skipCurrentLoop())