#include "llvm/Module.h"
#include "Support/STLExtras.h"
#include "Support/TypeInfo.h"
-#include <stdio.h>
-#include <sys/resource.h>
-#include <sys/time.h>
-#include <sys/unistd.h>
+#include "Config/stdio.h"
+#include "Config/sys/resource.h"
+#include "Config/sys/time.h"
+#include "Config/unistd.h"
#include <set>
// IncludeFile - Stub function used to help linking out.
// AnalysisUsage Class Implementation
//
-// preservesCFG - This function should be called to by the pass, iff they do
+// setPreservesCFG - This function should be called to by the pass, iff they do
// not:
//
// 1. Add or remove basic blocks from the function
// 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() {
+void AnalysisUsage::setPreservesCFG() {
// Since this transformation doesn't modify the CFG, it preserves all analyses
// that only depend on the CFG (like dominators, loop info, etc...)
//
void PassManager::add(Pass *P) { PM->add(P); }
bool PassManager::run(Module &M) { return PM->run(M); }
+//===----------------------------------------------------------------------===//
+// FunctionPassManager implementation - The FunctionPassManager class
+// is a simple Pimpl class that wraps the PassManagerT template. It
+// is like PassManager, but only deals in FunctionPasses.
+//
+FunctionPassManager::FunctionPassManager() : PM(new PassManagerT<Function>()) {}
+FunctionPassManager::~FunctionPassManager() { delete PM; }
+void FunctionPassManager::add(FunctionPass *P) { PM->add(P); }
+void FunctionPassManager::add(ImmutablePass *IP) { PM->add(IP); }
+bool FunctionPassManager::run(Function &F) { return PM->run(F); }
+
//===----------------------------------------------------------------------===//
// TimingInfo Class - This class is used to calculate information about the
EnableTiming("time-passes",
cl::desc("Time each pass, printing elapsed time for each on exit"));
-static TimeRecord getTimeRecord() {
- static unsigned long PageSize = 0;
-
- if (PageSize == 0) {
-#ifdef _SC_PAGE_SIZE
- PageSize = sysconf(_SC_PAGE_SIZE);
-#else
-#ifdef _SC_PAGESIZE
- PageSize = sysconf(_SC_PAGESIZE);
-#else
- PageSize = getpagesize();
-#endif
-#endif
- }
-
- struct rusage RU;
- struct timeval T;
- gettimeofday(&T, 0);
- if (getrusage(RUSAGE_SELF, &RU)) {
- perror("getrusage call failed: -time-passes info incorrect!");
- }
-
- TimeRecord Result;
- Result.Elapsed = T.tv_sec + T.tv_usec/1000000.0;
- Result.UserTime = RU.ru_utime.tv_sec + RU.ru_utime.tv_usec/1000000.0;
- Result.SystemTime = RU.ru_stime.tv_sec + RU.ru_stime.tv_usec/1000000.0;
- Result.MaxRSS = RU.ru_maxrss*PageSize;
-
- return Result;
-}
-
-bool TimeRecord::operator<(const TimeRecord &TR) const {
- // Primary sort key is User+System time
- if (UserTime+SystemTime < TR.UserTime+TR.SystemTime)
- return true;
- if (UserTime+SystemTime > TR.UserTime+TR.SystemTime)
- return false;
-
- // Secondary sort key is Wall Time
- return Elapsed < TR.Elapsed;
-}
-
-void TimeRecord::passStart(const TimeRecord &T) {
- Elapsed -= T.Elapsed;
- UserTime -= T.UserTime;
- SystemTime -= T.SystemTime;
- RSSTemp = T.MaxRSS;
-}
-
-void TimeRecord::passEnd(const TimeRecord &T) {
- Elapsed += T.Elapsed;
- UserTime += T.UserTime;
- SystemTime += T.SystemTime;
- RSSTemp = T.MaxRSS - RSSTemp;
- MaxRSS = std::max(MaxRSS, RSSTemp);
-}
-
-static void printVal(double Val, double Total) {
- if (Total < 1e-7) // Avoid dividing by zero...
- fprintf(stderr, " ----- ");
- else
- fprintf(stderr, " %7.4f (%5.1f%%)", Val, Val*100/Total);
-}
-
-void TimeRecord::print(const char *PassName, const TimeRecord &Total) const {
- printVal(UserTime, Total.UserTime);
- printVal(SystemTime, Total.SystemTime);
- printVal(UserTime+SystemTime, Total.UserTime+Total.SystemTime);
- printVal(Elapsed, Total.Elapsed);
-
- fprintf(stderr, " ");
-
- if (Total.MaxRSS)
- std::cerr << MaxRSS << "\t";
- std::cerr << PassName << "\n";
-}
-
-
-// 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].passStart(getTimeRecord());
-}
-void TimingInfo::passEnded(Pass *P) {
- TimingData[P].passEnd(getTimeRecord());
-}
-void TimeRecord::sum(const TimeRecord &TR) {
- Elapsed += TR.Elapsed;
- UserTime += TR.UserTime;
- SystemTime += TR.SystemTime;
- MaxRSS += TR.MaxRSS;
-}
-
-// 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<std::pair<TimeRecord, Pass*> > Data;
- TimeRecord Total;
- for (std::map<Pass*, TimeRecord>::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));
- Total.sum(I->second);
- }
-
- // Sort the data by time as the primary key, in reverse order...
- std::sort(Data.begin(), Data.end(),
- std::greater<std::pair<TimeRecord, Pass*> >());
-
- // Print out timing header...
- std::cerr << std::string(79, '=') << "\n"
- << " ... Pass execution timing report ...\n"
- << std::string(79, '=') << "\n Total Execution Time: "
- << (Total.UserTime+Total.SystemTime) << " seconds ("
- << Total.Elapsed << " wall clock)\n\n ---User Time--- "
- << "--System Time-- --User+System-- ---Wall Time---";
+// 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 (!EnableTiming || TheTimeInfo) return;
- if (Total.MaxRSS)
- std::cerr << " ---Mem---";
- std::cerr << " --- Pass Name ---\n";
-
- // Loop through all of the timing data, printing it out...
- for (unsigned i = 0, e = Data.size(); i != e; ++i)
- Data[i].first.print(Data[i].second->getPassName(), Total);
-
- Total.print("TOTAL", Total);
+ // 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 TimingInfo TTI;
+ TheTimeInfo = &TTI;
}
-
void PMDebug::PrintArgumentInformation(const Pass *P) {
// Print out passes in pass manager...
if (const AnalysisResolver *PM = dynamic_cast<const AnalysisResolver*>(P)) {
PM->addPass(this, AU);
}
+bool Pass::mustPreserveAnalysisID(const PassInfo *AnalysisID) const {
+ return Resolver->getAnalysisToUpdate(AnalysisID) != 0;
+}
+
// dumpPassStructure - Implement the -debug-passes=Structure option
void Pass::dumpPassStructure(unsigned Offset) {
std::cerr << std::string(Offset*2, ' ') << getPassName() << "\n";
}
// print - Print out the internal state of the pass. This is called by Analyse
-// to print out the contents of an analysis. Otherwise it is not neccesary to
+// to print out the contents of an analysis. Otherwise it is not necessary to
// implement this method.
//
void Pass::print(std::ostream &O) const {