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
|
||||
|
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/Module.h"
|
||||
#include "llvm/IR/OptBisect.h"
|
||||
#include "llvm/IR/PassTimingInfo.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/OptBisect.h"
|
||||
#include "llvm/IR/PassManager.h"
|
||||
#include "llvm/IR/PassTimingInfo.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/Timer.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
@ -15,6 +15,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
#include "llvm/Analysis/RegionPass.h"
|
||||
#include "llvm/IR/OptBisect.h"
|
||||
#include "llvm/IR/PassTimingInfo.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/Timer.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
@ -44,6 +44,7 @@ add_llvm_library(LLVMCore
|
||||
Pass.cpp
|
||||
PassManager.cpp
|
||||
PassRegistry.cpp
|
||||
PassTimingInfo.cpp
|
||||
SafepointIRVerifier.cpp
|
||||
ProfileSummary.cpp
|
||||
Statepoint.cpp
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include "llvm/IR/LegacyPassManagers.h"
|
||||
#include "llvm/IR/LegacyPassNameParser.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/IR/PassTimingInfo.h"
|
||||
#include "llvm/Support/Chrono.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
@ -494,65 +495,6 @@ char PassManagerImpl::ID = 0;
|
||||
} // End of legacy 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
|
||||
|
||||
@ -1527,7 +1469,6 @@ void FunctionPassManagerImpl::releaseMemoryOnTheFly() {
|
||||
// Return true if any function is modified by a pass.
|
||||
bool FunctionPassManagerImpl::run(Function &F) {
|
||||
bool Changed = false;
|
||||
TimingInfo::createTheTimeInfo();
|
||||
|
||||
initializeAllAnalysisInfo();
|
||||
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.
|
||||
bool PassManagerImpl::run(Module &M) {
|
||||
bool Changed = false;
|
||||
TimingInfo::createTheTimeInfo();
|
||||
|
||||
dumpArguments();
|
||||
dumpPasses();
|
||||
@ -1807,41 +1747,6 @@ bool PassManager::run(Module &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
|
||||
//
|
||||
|
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