diff options
author | Chris Lattner <sabre@nondot.org> | 2002-04-29 04:04:29 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2002-04-29 04:04:29 +0000 |
commit | 691fa3cfb12f459b953dd400057841b10ccf4b72 (patch) | |
tree | b0984995084cf6c21f7df06ebf5f99658204132c /lib/VMCore | |
parent | 63f824ce1815078b5a15edc5ecf1b57ac6f6aa04 (diff) | |
download | external_llvm-691fa3cfb12f459b953dd400057841b10ccf4b72.zip external_llvm-691fa3cfb12f459b953dd400057841b10ccf4b72.tar.gz external_llvm-691fa3cfb12f459b953dd400057841b10ccf4b72.tar.bz2 |
Add a new command line option for PassManager using utilities.
Now for llc, gccas, analyze, opt, etc you can specify the -time-passes
command line option that outputs a timing summary report that indicates
how long each pass takes to execute.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@2394 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/VMCore')
-rw-r--r-- | lib/VMCore/Pass.cpp | 60 | ||||
-rw-r--r-- | lib/VMCore/PassManagerT.h | 95 |
2 files changed, 144 insertions, 11 deletions
diff --git a/lib/VMCore/Pass.cpp b/lib/VMCore/Pass.cpp index c3c9d45..0344dd6 100644 --- a/lib/VMCore/Pass.cpp +++ b/lib/VMCore/Pass.cpp @@ -15,6 +15,8 @@ #include "Support/CommandLine.h" #include <typeinfo> #include <iostream> +#include <sys/time.h> +#include <stdio.h> // Source of unique analysis ID #'s. unsigned AnalysisID::NextID = 0; @@ -50,6 +52,64 @@ bool PassManager::run(Module *M) { return PM->run(M); } //===----------------------------------------------------------------------===// +// TimingInfo Class - This class is used to calculate information about the +// amount of time each pass takes to execute. This only happens with +// -time-passes is enabled on the command line. +// +static cl::Flag EnableTiming("time-passes", "Time each pass, printing elapsed" + " time for each on exit"); + +static double getTime() { + struct timeval T; + gettimeofday(&T, 0); + return T.tv_sec + T.tv_usec/1000000.0; +} + +// Create method. If Timing is enabled, this creates and returns a new timing +// object, otherwise it returns null. +// +TimingInfo *TimingInfo::create() { + return EnableTiming ? new TimingInfo() : 0; +} + +void TimingInfo::passStarted(Pass *P) { TimingData[P] -= getTime(); } +void TimingInfo::passEnded(Pass *P) { TimingData[P] += getTime(); } + +// TimingDtor - Print out information about timing information +TimingInfo::~TimingInfo() { + // Iterate over all of the data, converting it into the dual of the data map, + // so that the data is sorted by amount of time taken, instead of pointer. + // + std::vector<pair<double, Pass*> > Data; + double TotalTime = 0; + for (std::map<Pass*, double>::iterator I = TimingData.begin(), + E = TimingData.end(); I != E; ++I) + // Throw out results for "grouping" pass managers... + if (!dynamic_cast<AnalysisResolver*>(I->first)) { + Data.push_back(std::make_pair(I->second, I->first)); + TotalTime += I->second; + } + + // Sort the data by time as the primary key, in reverse order... + std::sort(Data.begin(), Data.end(), greater<pair<double, Pass*> >()); + + // Print out timing header... + cerr << std::string(79, '=') << "\n" + << " ... Pass execution timing report ...\n" + << std::string(79, '=') << "\n Total Execution Time: " << TotalTime + << " seconds\n\n % Time: Seconds:\tPass Name (mangled):\n"; + + // Loop through all of the timing data, printing it out... + for (unsigned i = 0, e = Data.size(); i != e; ++i) { + fprintf(stderr, " %6.2f%% %fs\t%s\n", Data[i].first*100 / TotalTime, + Data[i].first, typeid(*Data[i].second).name()); + } + cerr << " 100.00% " << TotalTime << "s\tTOTAL\n" + << std::string(79, '=') << "\n"; +} + + +//===----------------------------------------------------------------------===// // Pass debugging information. Often it is useful to find out what pass is // running when a crash occurs in a utility. When this library is compiled with // debugging on, a command line option (--debug-pass) is enabled that causes the diff --git a/lib/VMCore/PassManagerT.h b/lib/VMCore/PassManagerT.h index eb80740..8d1716b 100644 --- a/lib/VMCore/PassManagerT.h +++ b/lib/VMCore/PassManagerT.h @@ -35,6 +35,28 @@ struct PMDebug { }; +//===----------------------------------------------------------------------===// +// 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. +// +class TimingInfo { + std::map<Pass*, double> TimingData; + TimingInfo() {} // Private ctor, must use create member +public: + // Create method. If Timing is enabled, this creates and returns a new timing + // object, otherwise it returns null. + // + static TimingInfo *create(); + + // TimingDtor - Print out information about timing information + ~TimingInfo(); + + void passStarted(Pass *P); + void passEnded(Pass *P); +}; + + //===----------------------------------------------------------------------===// // Declare the PassManagerTraits which will be specialized... @@ -49,15 +71,15 @@ template<class UnitType> class PassManagerTraits; // Do not define. // template<typename UnitType> class PassManagerT : public PassManagerTraits<UnitType>,public AnalysisResolver{ - typedef typename PassManagerTraits<UnitType>::PassClass PassClass; - typedef typename PassManagerTraits<UnitType>::SubPassClass SubPassClass; - typedef typename PassManagerTraits<UnitType>::BatcherClass BatcherClass; - typedef typename PassManagerTraits<UnitType>::ParentClass ParentClass; - typedef PassManagerTraits<UnitType> Traits; + typedef PassManagerTraits<UnitType> Traits; + typedef typename Traits::PassClass PassClass; + typedef typename Traits::SubPassClass SubPassClass; + typedef typename Traits::BatcherClass BatcherClass; + typedef typename Traits::ParentClass ParentClass; - friend typename PassManagerTraits<UnitType>::PassClass; - friend typename PassManagerTraits<UnitType>::SubPassClass; - friend class PassManagerTraits<UnitType>; + friend typename Traits::PassClass; + friend typename Traits::SubPassClass; + friend class Traits; std::vector<PassClass*> Passes; // List of pass's to run @@ -128,7 +150,9 @@ public: #endif // Run the sub pass! - bool Changed = Traits::runPass(P, M); + startPass(P); + bool Changed = runPass(P, M); + endPass(P); MadeChanges |= Changed; if (Changed) @@ -217,6 +241,20 @@ public: return I->second; } + // {start/end}Pass - Called when a pass is started, it just propogates + // information up to the top level PassManagerT object to tell it that a pass + // has started or ended. This is used to gather timing information about + // passes. + // + void startPass(Pass *P) { + if (Parent) Parent->startPass(P); + else PassStarted(P); + } + void endPass(Pass *P) { + if (Parent) Parent->endPass(P); + else PassEnded(P); + } + // markPassUsed - Inform higher level pass managers (and ourselves) // that these analyses are being used by this pass. This is used to // make sure that analyses are not free'd before we have to use @@ -389,6 +427,10 @@ template<> struct PassManagerTraits<BasicBlock> : public BasicBlockPass { return P->runOnBasicBlock(M); } + // Dummy implementation of PassStarted/PassEnded + static void PassStarted(Pass *P) {} + static void PassEnded(Pass *P) {} + // getPMName() - Return the name of the unit the PassManager operates on for // debugging. const char *getPMName() const { return "BasicBlock"; } @@ -428,6 +470,10 @@ template<> struct PassManagerTraits<Function> : public FunctionPass { return P->runOnFunction(F); } + // Dummy implementation of PassStarted/PassEnded + static void PassStarted(Pass *P) {} + static void PassEnded(Pass *P) {} + // getPMName() - Return the name of the unit the PassManager operates on for // debugging. const char *getPMName() const { return "Function"; } @@ -465,10 +511,37 @@ template<> struct PassManagerTraits<Module> : public Pass { // debugging. const char *getPMName() const { return "Module"; } - // run - Implement the Pass interface... + // TimingInformation - This data member maintains timing information for each + // of the passes that is executed. + // + TimingInfo *TimeInfo; + + // PassStarted/Ended - This callback is notified any time a pass is started + // or stops. This is used to collect timing information about the different + // passes being executed. + // + void PassStarted(Pass *P) { + if (TimeInfo) TimeInfo->passStarted(P); + } + void PassEnded(Pass *P) { + if (TimeInfo) TimeInfo->passEnded(P); + } + + // run - Implement the PassManager interface... bool run(Module *M) { - return ((PassManagerT<Module>*)this)->runOnUnit(M); + TimeInfo = TimingInfo::create(); + bool Result = ((PassManagerT<Module>*)this)->runOnUnit(M); + if (TimeInfo) { + delete TimeInfo; + TimeInfo = 0; + } + return Result; } + + // PassManagerTraits constructor - Create a timing info object if the user + // specified timing info should be collected on the command line. + // + PassManagerTraits() : TimeInfo(0) {} }; |