#include "llvm/Pass.h"
#include "Support/CommandLine.h"
+#include "Support/LeakDetector.h"
#include <algorithm>
#include <iostream>
class Annotable;
// amount of time each pass takes to execute. This only happens when
// -time-passes is enabled on the command line.
//
+struct TimeRecord { // TimeRecord - Data we collect and print for each pass
+ double Elapsed; // Wall clock time elapsed in seconds
+ double UserTime; // User time elapsed
+ double SystemTime; // System time elapsed
+ unsigned long MaxRSS; // Maximum resident set size (in bytes)
+ unsigned long RSSTemp; // Temp for calculating maxrss
+
+ TimeRecord() : Elapsed(0), UserTime(0), SystemTime(0), MaxRSS(0) {}
+ void passStart(const TimeRecord &T);
+ void passEnd(const TimeRecord &T);
+ void sum(const TimeRecord &TR);
+ bool operator<(const TimeRecord &TR) const;
+
+ void print(const char *PassName, const TimeRecord &TotalTime) const;
+};
+
class TimingInfo {
- std::map<Pass*, double> TimingData;
+ std::map<Pass*, TimeRecord> TimingData;
TimingInfo() {} // Private ctor, must use create member
public:
// Create method. If Timing is enabled, this creates and returns a new timing
void passEnded(Pass *P);
};
-
-
//===----------------------------------------------------------------------===//
// Declare the PassManagerTraits which will be specialized...
//
PMDebug::PrintAnalysisSetInfo(getDepth(), "Required", P,
AnUsage.getRequiredSet());
-#ifndef NDEBUG
- // All Required analyses should be available to the pass as it runs!
- for (std::vector<AnalysisID>::const_iterator
+ // All Required analyses should be available to the pass as it runs! Here
+ // we fill in the AnalysisImpls member of the pass so that it can
+ // successfully use the getAnalysis() method to retrieve the
+ // implementations it needs.
+ //
+ P->AnalysisImpls.clear();
+ P->AnalysisImpls.reserve(AnUsage.getRequiredSet().size());
+ for (std::vector<const PassInfo *>::const_iterator
I = AnUsage.getRequiredSet().begin(),
E = AnUsage.getRequiredSet().end(); I != E; ++I) {
- assert(getAnalysisOrNullUp(*I) && "Analysis used but not available!");
+ Pass *Impl = getAnalysisOrNullUp(*I);
+ if (Impl == 0) {
+ std::cerr << "Analysis '" << (*I)->getPassName()
+ << "' used but not available!";
+ assert(0 && "Analysis used but not available!");
+ } else if (PassDebugging == Details) {
+ if ((*I)->getPassName() != std::string(Impl->getPassName()))
+ std::cerr << " Interface '" << (*I)->getPassName()
+ << "' implemented by '" << Impl->getPassName() << "'\n";
+ }
+ P->AnalysisImpls.push_back(std::make_pair(*I, Impl));
}
-#endif
// Run the sub pass!
startPass(P);
endPass(P);
MadeChanges |= Changed;
+ // Check for memory leaks by the pass...
+ LeakDetector::checkForGarbage(std::string("after running pass '") +
+ P->getPassName() + "'");
+
if (Changed)
PMDebug::PrintPassInformation(getDepth()+1, "Made Modification", P,
(Annotable*)M);
// Add the current pass to the set of passes that have been run, and are
// thus available to users.
//
- if (const PassInfo *PI = P->getPassInfo())
+ if (const PassInfo *PI = P->getPassInfo()) {
CurrentAnalyses[PI] = P;
+ // This pass is the current implementation of all of the interfaces it
+ // implements as well.
+ //
+ const std::vector<const PassInfo*> &II = PI->getInterfacesImplemented();
+ for (unsigned i = 0, e = II.size(); i != e; ++i)
+ CurrentAnalyses[II[i]] = P;
+ }
+
// Free memory for any passes that we are the last use of...
std::vector<Pass*> &DeadPass = LastUserOf[P];
for (std::vector<Pass*>::iterator I = DeadPass.begin(),E = DeadPass.end();
}
}
- Pass *getAnalysisOrNullDown(AnalysisID ID) const {
+ Pass *getAnalysisOrNullDown(const PassInfo *ID) const {
std::map<AnalysisID, Pass*>::const_iterator I = CurrentAnalyses.find(ID);
- if (I == CurrentAnalyses.end()) {
- if (Batcher)
- return ((AnalysisResolver*)Batcher)->getAnalysisOrNullDown(ID);
- return 0;
- }
- return I->second;
+
+ if (I != CurrentAnalyses.end())
+ return I->second; // Found it.
+
+ if (Batcher)
+ return ((AnalysisResolver*)Batcher)->getAnalysisOrNullDown(ID);
+ return 0;
}
- Pass *getAnalysisOrNullUp(AnalysisID ID) const {
+ Pass *getAnalysisOrNullUp(const PassInfo *ID) const {
std::map<AnalysisID, Pass*>::const_iterator I = CurrentAnalyses.find(ID);
- if (I == CurrentAnalyses.end()) {
- if (Parent)
- return Parent->getAnalysisOrNullUp(ID);
- return 0;
- }
- return I->second;
+ if (I != CurrentAnalyses.end())
+ return I->second; // Found it.
+
+ if (Parent) // Try scanning...
+ return Parent->getAnalysisOrNullUp(ID);
+ return 0;
}
// {start/end}Pass - Called when a pass is started, it just propogates
// make sure that analyses are not free'd before we have to use
// them...
//
- void markPassUsed(AnalysisID P, Pass *User) {
- std::map<AnalysisID, Pass*>::iterator I = CurrentAnalyses.find(P);
+ void markPassUsed(const PassInfo *P, Pass *User) {
+ std::map<AnalysisID, Pass*>::const_iterator I = CurrentAnalyses.find(P);
+
if (I != CurrentAnalyses.end()) {
LastUseOf[I->second] = User; // Local pass, extend the lifetime
} else {
// parent that we (the passmanager) are using the analysis so that it
// frees the analysis AFTER this pass manager runs.
//
- assert(Parent != 0 && "Pass available but not found! "
- "Did your analysis pass 'Provide' itself?");
+ assert(Parent != 0 && "Pass available but not found!");
Parent->markPassUsed(P, this);
}
}
return Passes[N];
}
- // add - Add a pass to the queue of passes to run. This passes ownership of
+ // add - Add a pass to the queue of passes to run. This gives ownership of
// the Pass to the PassManager. When the PassManager is destroyed, the pass
// will be destroyed as well, so there is no need to delete the pass. This
// implies that all passes MUST be new'd.
}
// Add this pass to the currently available set...
- if (const PassInfo *PI = P->getPassInfo())
+ if (const PassInfo *PI = P->getPassInfo()) {
CurrentAnalyses[PI] = P;
+ // This pass is the current implementation of all of the interfaces it
+ // implements as well.
+ //
+ const std::vector<const PassInfo*> &II = PI->getInterfacesImplemented();
+ for (unsigned i = 0, e = II.size(); i != e; ++i)
+ CurrentAnalyses[II[i]] = P;
+ }
+
// For now assume that our results are never used...
LastUseOf[P] = P;
}