mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-05-13 18:45:55 +00:00
[NFC][PassTiming] factor out generic PassTimingInfo
Moving PassTimingInfo from legacy pass manager code into a separate header. Making it suitable for both legacy and new pass manager. Adding a test on -time-passes main functionality. llvm-svn: 340872
This commit is contained in:
parent
da787801e8
commit
3dcc0c90de
@ -508,7 +508,6 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Timer *getPassTimer(Pass *);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
69
include/llvm/IR/PassTimingInfo.h
Normal file
69
include/llvm/IR/PassTimingInfo.h
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
//===- PassTimingInfo.h - pass execution timing -----------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is distributed under the University of Illinois Open Source
|
||||||
|
// License. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
/// \file
|
||||||
|
///
|
||||||
|
/// This header defines classes/functions to handle pass execution timing
|
||||||
|
/// information with an interface suitable for both pass managers.
|
||||||
|
///
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#ifndef LLVM_IR_PASSTIMINGINFO_H
|
||||||
|
#define LLVM_IR_PASSTIMINGINFO_H
|
||||||
|
|
||||||
|
#include "llvm/ADT/StringMap.h"
|
||||||
|
#include "llvm/ADT/StringRef.h"
|
||||||
|
#include "llvm/Support/Timer.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
|
||||||
|
class Pass;
|
||||||
|
class TimerGroup;
|
||||||
|
|
||||||
|
/// Provides a generic interface for collecting pass timing information.
|
||||||
|
/// Legacy pass managers should specialize with \p PassInfo*.
|
||||||
|
/// New pass managers should specialize with \p StringRef.
|
||||||
|
template <typename PassInfoT> class PassTimingInfo {
|
||||||
|
StringMap<Timer *> TimingData;
|
||||||
|
TimerGroup TG;
|
||||||
|
|
||||||
|
public:
|
||||||
|
/// Default constructor for yet-inactive timeinfo.
|
||||||
|
/// Use \p init() to activate it.
|
||||||
|
PassTimingInfo();
|
||||||
|
|
||||||
|
/// Print out timing information and release timers.
|
||||||
|
~PassTimingInfo();
|
||||||
|
|
||||||
|
/// Initializes the static \p TheTimeInfo member to a non-null value when
|
||||||
|
/// -time-passes is enabled. Leaves it null otherwise.
|
||||||
|
///
|
||||||
|
/// This method may be called multiple times.
|
||||||
|
static void init();
|
||||||
|
|
||||||
|
/// Prints out timing information and then resets the timers.
|
||||||
|
void print();
|
||||||
|
|
||||||
|
/// Returns the timer for the specified pass if it exists.
|
||||||
|
Timer *getPassTimer(PassInfoT);
|
||||||
|
|
||||||
|
static PassTimingInfo *TheTimeInfo;
|
||||||
|
};
|
||||||
|
|
||||||
|
Timer *getPassTimer(Pass *);
|
||||||
|
Timer *getPassTimer(StringRef);
|
||||||
|
|
||||||
|
/// If the user specifies the -time-passes argument on an LLVM tool command line
|
||||||
|
/// then the value of this boolean will be true, otherwise false.
|
||||||
|
/// This is the storage for the -time-passes option.
|
||||||
|
extern bool TimePassesIsEnabled;
|
||||||
|
|
||||||
|
} // namespace llvm
|
||||||
|
|
||||||
|
#endif
|
@ -27,6 +27,7 @@
|
|||||||
#include "llvm/IR/LegacyPassManagers.h"
|
#include "llvm/IR/LegacyPassManagers.h"
|
||||||
#include "llvm/IR/Module.h"
|
#include "llvm/IR/Module.h"
|
||||||
#include "llvm/IR/OptBisect.h"
|
#include "llvm/IR/OptBisect.h"
|
||||||
|
#include "llvm/IR/PassTimingInfo.h"
|
||||||
#include "llvm/Pass.h"
|
#include "llvm/Pass.h"
|
||||||
#include "llvm/Support/CommandLine.h"
|
#include "llvm/Support/CommandLine.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "llvm/IR/LLVMContext.h"
|
#include "llvm/IR/LLVMContext.h"
|
||||||
#include "llvm/IR/OptBisect.h"
|
#include "llvm/IR/OptBisect.h"
|
||||||
#include "llvm/IR/PassManager.h"
|
#include "llvm/IR/PassManager.h"
|
||||||
|
#include "llvm/IR/PassTimingInfo.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
#include "llvm/Support/Timer.h"
|
#include "llvm/Support/Timer.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
#include "llvm/Analysis/RegionPass.h"
|
#include "llvm/Analysis/RegionPass.h"
|
||||||
#include "llvm/IR/OptBisect.h"
|
#include "llvm/IR/OptBisect.h"
|
||||||
|
#include "llvm/IR/PassTimingInfo.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
#include "llvm/Support/Timer.h"
|
#include "llvm/Support/Timer.h"
|
||||||
#include "llvm/Support/raw_ostream.h"
|
#include "llvm/Support/raw_ostream.h"
|
||||||
|
@ -44,6 +44,7 @@ add_llvm_library(LLVMCore
|
|||||||
Pass.cpp
|
Pass.cpp
|
||||||
PassManager.cpp
|
PassManager.cpp
|
||||||
PassRegistry.cpp
|
PassRegistry.cpp
|
||||||
|
PassTimingInfo.cpp
|
||||||
SafepointIRVerifier.cpp
|
SafepointIRVerifier.cpp
|
||||||
ProfileSummary.cpp
|
ProfileSummary.cpp
|
||||||
Statepoint.cpp
|
Statepoint.cpp
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "llvm/IR/LegacyPassManagers.h"
|
#include "llvm/IR/LegacyPassManagers.h"
|
||||||
#include "llvm/IR/LegacyPassNameParser.h"
|
#include "llvm/IR/LegacyPassNameParser.h"
|
||||||
#include "llvm/IR/Module.h"
|
#include "llvm/IR/Module.h"
|
||||||
|
#include "llvm/IR/PassTimingInfo.h"
|
||||||
#include "llvm/Support/Chrono.h"
|
#include "llvm/Support/Chrono.h"
|
||||||
#include "llvm/Support/CommandLine.h"
|
#include "llvm/Support/CommandLine.h"
|
||||||
#include "llvm/Support/Debug.h"
|
#include "llvm/Support/Debug.h"
|
||||||
@ -494,65 +495,6 @@ char PassManagerImpl::ID = 0;
|
|||||||
} // End of legacy namespace
|
} // End of legacy namespace
|
||||||
} // End of llvm namespace
|
} // End of llvm namespace
|
||||||
|
|
||||||
namespace {
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
/// TimingInfo Class - This class is used to calculate information about the
|
|
||||||
/// amount of time each pass takes to execute. This only happens when
|
|
||||||
/// -time-passes is enabled on the command line.
|
|
||||||
///
|
|
||||||
|
|
||||||
static ManagedStatic<sys::SmartMutex<true> > TimingInfoMutex;
|
|
||||||
|
|
||||||
class TimingInfo {
|
|
||||||
DenseMap<Pass*, Timer*> TimingData;
|
|
||||||
TimerGroup TG;
|
|
||||||
public:
|
|
||||||
// Use 'create' member to get this.
|
|
||||||
TimingInfo() : TG("pass", "... Pass execution timing report ...") {}
|
|
||||||
|
|
||||||
// TimingDtor - Print out information about timing information
|
|
||||||
~TimingInfo() {
|
|
||||||
// Delete all of the timers, which accumulate their info into the
|
|
||||||
// TimerGroup.
|
|
||||||
for (auto &I : TimingData)
|
|
||||||
delete I.second;
|
|
||||||
// TimerGroup is deleted next, printing the report.
|
|
||||||
}
|
|
||||||
|
|
||||||
// createTheTimeInfo - This method either initializes the TheTimeInfo pointer
|
|
||||||
// to a non-null value (if the -time-passes option is enabled) or it leaves it
|
|
||||||
// null. It may be called multiple times.
|
|
||||||
static void createTheTimeInfo();
|
|
||||||
|
|
||||||
// print - Prints out timing information and then resets the timers.
|
|
||||||
void print() {
|
|
||||||
TG.print(*CreateInfoOutputFile());
|
|
||||||
}
|
|
||||||
|
|
||||||
/// getPassTimer - Return the timer for the specified pass if it exists.
|
|
||||||
Timer *getPassTimer(Pass *P) {
|
|
||||||
if (P->getAsPMDataManager())
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
sys::SmartScopedLock<true> Lock(*TimingInfoMutex);
|
|
||||||
Timer *&T = TimingData[P];
|
|
||||||
if (!T) {
|
|
||||||
StringRef PassName = P->getPassName();
|
|
||||||
StringRef PassArgument;
|
|
||||||
if (const PassInfo *PI = Pass::lookupPassInfo(P->getPassID()))
|
|
||||||
PassArgument = PI->getPassArgument();
|
|
||||||
T = new Timer(PassArgument.empty() ? PassName : PassArgument, PassName,
|
|
||||||
TG);
|
|
||||||
}
|
|
||||||
return T;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
} // End of anon namespace
|
|
||||||
|
|
||||||
static TimingInfo *TheTimeInfo;
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// PMTopLevelManager implementation
|
// PMTopLevelManager implementation
|
||||||
|
|
||||||
@ -1527,7 +1469,6 @@ void FunctionPassManagerImpl::releaseMemoryOnTheFly() {
|
|||||||
// Return true if any function is modified by a pass.
|
// Return true if any function is modified by a pass.
|
||||||
bool FunctionPassManagerImpl::run(Function &F) {
|
bool FunctionPassManagerImpl::run(Function &F) {
|
||||||
bool Changed = false;
|
bool Changed = false;
|
||||||
TimingInfo::createTheTimeInfo();
|
|
||||||
|
|
||||||
initializeAllAnalysisInfo();
|
initializeAllAnalysisInfo();
|
||||||
for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) {
|
for (unsigned Index = 0; Index < getNumContainedManagers(); ++Index) {
|
||||||
@ -1763,7 +1704,6 @@ Pass* MPPassManager::getOnTheFlyPass(Pass *MP, AnalysisID PI, Function &F){
|
|||||||
/// whether any of the passes modifies the module, and if so, return true.
|
/// whether any of the passes modifies the module, and if so, return true.
|
||||||
bool PassManagerImpl::run(Module &M) {
|
bool PassManagerImpl::run(Module &M) {
|
||||||
bool Changed = false;
|
bool Changed = false;
|
||||||
TimingInfo::createTheTimeInfo();
|
|
||||||
|
|
||||||
dumpArguments();
|
dumpArguments();
|
||||||
dumpPasses();
|
dumpPasses();
|
||||||
@ -1807,41 +1747,6 @@ bool PassManager::run(Module &M) {
|
|||||||
return PM->run(M);
|
return PM->run(M);
|
||||||
}
|
}
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
|
||||||
// TimingInfo implementation
|
|
||||||
|
|
||||||
bool llvm::TimePassesIsEnabled = false;
|
|
||||||
static cl::opt<bool, true> EnableTiming(
|
|
||||||
"time-passes", cl::location(TimePassesIsEnabled), cl::Hidden,
|
|
||||||
cl::desc("Time each pass, printing elapsed time for each on exit"));
|
|
||||||
|
|
||||||
// createTheTimeInfo - This method either initializes the TheTimeInfo pointer to
|
|
||||||
// a non-null value (if the -time-passes option is enabled) or it leaves it
|
|
||||||
// null. It may be called multiple times.
|
|
||||||
void TimingInfo::createTheTimeInfo() {
|
|
||||||
if (!TimePassesIsEnabled || TheTimeInfo) return;
|
|
||||||
|
|
||||||
// Constructed the first time this is called, iff -time-passes is enabled.
|
|
||||||
// This guarantees that the object will be constructed before static globals,
|
|
||||||
// thus it will be destroyed before them.
|
|
||||||
static ManagedStatic<TimingInfo> TTI;
|
|
||||||
TheTimeInfo = &*TTI;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// If TimingInfo is enabled then start pass timer.
|
|
||||||
Timer *llvm::getPassTimer(Pass *P) {
|
|
||||||
if (TheTimeInfo)
|
|
||||||
return TheTimeInfo->getPassTimer(P);
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// If timing is enabled, report the times collected up to now and then reset
|
|
||||||
/// them.
|
|
||||||
void llvm::reportAndResetTimings() {
|
|
||||||
if (TheTimeInfo)
|
|
||||||
TheTimeInfo->print();
|
|
||||||
}
|
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// PMStack implementation
|
// PMStack implementation
|
||||||
//
|
//
|
||||||
|
132
lib/IR/PassTimingInfo.cpp
Normal file
132
lib/IR/PassTimingInfo.cpp
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
//===- PassTimingInfo.cpp - LLVM Pass Timing Implementation ---------------===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is distributed under the University of Illinois Open Source
|
||||||
|
// License. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This file implements the LLVM Pass Timing infrastructure for both
|
||||||
|
// new and legacy pass managers.
|
||||||
|
//
|
||||||
|
// TimingInfo Class - This class is used to calculate information about the
|
||||||
|
// amount of time each pass takes to execute. This only happens when
|
||||||
|
// -time-passes is enabled on the command line.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "llvm/IR/PassTimingInfo.h"
|
||||||
|
#include "llvm/ADT/DenseMap.h"
|
||||||
|
#include "llvm/ADT/Statistic.h"
|
||||||
|
#include "llvm/ADT/StringRef.h"
|
||||||
|
#include "llvm/Pass.h"
|
||||||
|
#include "llvm/Support/CommandLine.h"
|
||||||
|
#include "llvm/Support/Debug.h"
|
||||||
|
#include "llvm/Support/ManagedStatic.h"
|
||||||
|
#include "llvm/Support/Mutex.h"
|
||||||
|
#include "llvm/Support/Timer.h"
|
||||||
|
#include "llvm/Support/raw_ostream.h"
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
using namespace llvm;
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
// TimingInfo implementation
|
||||||
|
|
||||||
|
bool TimePassesIsEnabled = false;
|
||||||
|
static cl::opt<bool, true> EnableTiming(
|
||||||
|
"time-passes", cl::location(TimePassesIsEnabled), cl::Hidden,
|
||||||
|
cl::desc("Time each pass, printing elapsed time for each on exit"));
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
static ManagedStatic<sys::SmartMutex<true>> TimingInfoMutex;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename PassT>
|
||||||
|
PassTimingInfo<PassT>::PassTimingInfo()
|
||||||
|
: TG("pass", "... Pass execution timing report ...") {}
|
||||||
|
|
||||||
|
template <typename PassT> PassTimingInfo<PassT>::~PassTimingInfo() {
|
||||||
|
// Deleting the timers accumulates their info into the TG member.
|
||||||
|
// Then TG member is (implicitly) deleted, actually printing the report.
|
||||||
|
for (auto &I : TimingData)
|
||||||
|
delete I.getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename PassT> void PassTimingInfo<PassT>::init() {
|
||||||
|
if (!TimePassesIsEnabled || TheTimeInfo)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Constructed the first time this is called, iff -time-passes is enabled.
|
||||||
|
// This guarantees that the object will be constructed before static globals,
|
||||||
|
// thus it will be destroyed before them.
|
||||||
|
static ManagedStatic<PassTimingInfo> TTI;
|
||||||
|
TheTimeInfo = &*TTI;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Prints out timing information and then resets the timers.
|
||||||
|
template <typename PassT> void PassTimingInfo<PassT>::print() {
|
||||||
|
TG.print(*CreateInfoOutputFile());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return the timer for the specified pass if it exists.
|
||||||
|
template <> Timer *PassTimingInfo<StringRef>::getPassTimer(StringRef PassName) {
|
||||||
|
init();
|
||||||
|
sys::SmartScopedLock<true> Lock(*TimingInfoMutex);
|
||||||
|
Timer *&T = TimingData[PassName];
|
||||||
|
if (!T)
|
||||||
|
T = new Timer(PassName, PassName, TG);
|
||||||
|
return T;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <> Timer *PassTimingInfo<Pass *>::getPassTimer(Pass *P) {
|
||||||
|
if (P->getAsPMDataManager())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
init();
|
||||||
|
sys::SmartScopedLock<true> Lock(*TimingInfoMutex);
|
||||||
|
StringRef PassName = P->getPassName();
|
||||||
|
Timer *&T = TimingData[PassName];
|
||||||
|
|
||||||
|
if (!T) {
|
||||||
|
StringRef PassArgument;
|
||||||
|
if (const PassInfo *PI = Pass::lookupPassInfo(P->getPassID()))
|
||||||
|
PassArgument = PI->getPassArgument();
|
||||||
|
T = new Timer(PassArgument.empty() ? PassName : PassArgument, PassName, TG);
|
||||||
|
}
|
||||||
|
return T;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename PassInfoT>
|
||||||
|
PassTimingInfo<PassInfoT> *PassTimingInfo<PassInfoT>::TheTimeInfo;
|
||||||
|
|
||||||
|
template class PassTimingInfo<Pass *>;
|
||||||
|
template class PassTimingInfo<StringRef>;
|
||||||
|
|
||||||
|
Timer *getPassTimer(Pass *P) {
|
||||||
|
PassTimingInfo<Pass *>::init();
|
||||||
|
if (PassTimingInfo<Pass *>::TheTimeInfo)
|
||||||
|
return PassTimingInfo<Pass *>::TheTimeInfo->getPassTimer(P);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
Timer *getPassTimer(StringRef PassName) {
|
||||||
|
PassTimingInfo<StringRef>::init();
|
||||||
|
if (PassTimingInfo<StringRef>::TheTimeInfo)
|
||||||
|
return PassTimingInfo<StringRef>::TheTimeInfo->getPassTimer(PassName);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// If timing is enabled, report the times collected up to now and then reset
|
||||||
|
/// them.
|
||||||
|
void reportAndResetTimings() {
|
||||||
|
if (PassTimingInfo<StringRef>::TheTimeInfo)
|
||||||
|
PassTimingInfo<StringRef>::TheTimeInfo->print();
|
||||||
|
if (PassTimingInfo<Pass *>::TheTimeInfo)
|
||||||
|
PassTimingInfo<Pass *>::TheTimeInfo->print();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace llvm
|
15
test/Other/time-passes.ll
Normal file
15
test/Other/time-passes.ll
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
; RUN: opt < %s -disable-output -instcombine -time-passes 2>&1 | FileCheck %s --check-prefix=TIME --check-prefix=TIME-LEGACY
|
||||||
|
;
|
||||||
|
; TIME: Pass execution timing report
|
||||||
|
; TIME: Total Execution Time:
|
||||||
|
; TIME: Name
|
||||||
|
; TIME-LEGACY-DAG: Combine redundant instructions
|
||||||
|
; TIME-LEGACY-DAG: Dominator Tree Construction
|
||||||
|
; TIME-LEGACY-DAG: Module Verifier
|
||||||
|
; TIME-LEGACY-DAG: Target Library Information
|
||||||
|
; TIME: 100{{.*}} Total{{$}}
|
||||||
|
|
||||||
|
define i32 @foo() {
|
||||||
|
%res = add i32 5, 4
|
||||||
|
ret i32 %res
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user