X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FPass.cpp;h=48e608e90a41b77b7dc25238d34fa17d682548d0;hb=ee37bb34d133060318966b26317e063a1fee0c5f;hp=ff9ac928b9698283b64b8c65d2f93a8aa3d2cf19;hpb=d30efaf56ed1e374240b4c2fe2ea7054cbd7cb52;p=oota-llvm.git diff --git a/lib/VMCore/Pass.cpp b/lib/VMCore/Pass.cpp index ff9ac928b96..48e608e90a4 100644 --- a/lib/VMCore/Pass.cpp +++ b/lib/VMCore/Pass.cpp @@ -15,6 +15,8 @@ #include "Support/CommandLine.h" #include #include +#include +#include // Source of unique analysis ID #'s. unsigned AnalysisID::NextID = 0; @@ -24,6 +26,21 @@ void AnalysisResolver::setAnalysisResolver(Pass *P, AnalysisResolver *AR) { P->Resolver = AR; } + +// preservesCFG - This function should be called to by the pass, iff they do +// not: +// +// 1. Add or remove basic blocks from the function +// 2. Modify terminator instructions in any way. +// +// This function annotates the AnalysisUsage info object to say that analyses +// that only depend on the CFG are preserved by this pass. +// +void AnalysisUsage::preservesCFG() { + // FIXME: implement preservesCFG +} + + //===----------------------------------------------------------------------===// // PassManager implementation - The PassManager class is a simple Pimpl class // that wraps the PassManagerT template. @@ -34,6 +51,64 @@ void PassManager::add(Pass *P) { PM->add(P); } 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 > Data; + double TotalTime = 0; + for (std::map::iterator I = TimingData.begin(), + E = TimingData.end(); I != E; ++I) + // Throw out results for "grouping" pass managers... + if (!dynamic_cast(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 >()); + + // 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:\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, Data[i].second->getPassName()); + } + 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 @@ -62,7 +137,7 @@ void PMDebug::PrintPassInformation(unsigned Depth, const char *Action, Pass *P, Annotable *V) { if (PassDebugging >= PassExecutions) { std::cerr << (void*)P << std::string(Depth*2+1, ' ') << Action << " '" - << typeid(*P).name(); + << P->getPassName(); if (V) { std::cerr << "' on "; @@ -85,7 +160,7 @@ void PMDebug::PrintAnalysisSetInfo(unsigned Depth, const char *Msg, std::cerr << (void*)P << std::string(Depth*2+3, ' ') << Msg << " Analyses:"; for (unsigned i = 0; i != Set.size(); ++i) { Pass *P = Set[i].createPass(); // Good thing this is just debug code... - std::cerr << " " << typeid(*P).name(); + std::cerr << " " << P->getPassName(); delete P; } std::cerr << "\n"; @@ -94,7 +169,7 @@ void PMDebug::PrintAnalysisSetInfo(unsigned Depth, const char *Msg, // dumpPassStructure - Implement the -debug-passes=PassStructure option void Pass::dumpPassStructure(unsigned Offset = 0) { - std::cerr << std::string(Offset*2, ' ') << typeid(*this).name() << "\n"; + std::cerr << std::string(Offset*2, ' ') << getPassName() << "\n"; } @@ -106,6 +181,11 @@ void Pass::addToPassManager(PassManagerT *PM, AnalysisUsage &AU) { PM->addPass(this, AU); } + +// getPassName - Use C++ RTTI to get a SOMEWHAT intelligable name for the pass. +// +const char *Pass::getPassName() const { return typeid(*this).name(); } + //===----------------------------------------------------------------------===// // FunctionPass Implementation // @@ -142,20 +222,6 @@ void FunctionPass::addToPassManager(PassManagerT *PM, PM->addPass(this, AU); } -// doesNotModifyCFG - This function should be called by our subclasses to -// implement the getAnalysisUsage virtual function, iff they do not: -// -// 1. Add or remove basic blocks from the function -// 2. Modify terminator instructions in any way. -// -// This function annotates the AnalysisUsage info object to say that analyses -// that only depend on the CFG are preserved by this pass. -// -void FunctionPass::doesNotModifyCFG(AnalysisUsage &Info) { - -} - - //===----------------------------------------------------------------------===// // BasicBlockPass Implementation //