#define LLVM_PASSMANAGER_T_H
#include "llvm/Pass.h"
-#include <string>
+#include "Support/CommandLine.h"
#include <algorithm>
+#include <iostream>
class Annotable;
+//===----------------------------------------------------------------------===//
+// 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
+// pass name to be printed before it executes.
+//
+
+// Different debug levels that can be enabled...
+enum PassDebugLevel {
+ None, Arguments, Structure, Executions, Details
+};
+
+static cl::opt<enum PassDebugLevel>
+PassDebugging("debug-pass", cl::Hidden,
+ cl::desc("Print PassManager debugging information"),
+ cl::values(
+ clEnumVal(None , "disable debug output"),
+ clEnumVal(Arguments , "print pass arguments to pass to 'opt'"),
+ clEnumVal(Structure , "print pass structure before run()"),
+ clEnumVal(Executions, "print pass name before it is executed"),
+ clEnumVal(Details , "print pass details when it is executed"),
+ 0));
+
//===----------------------------------------------------------------------===//
// PMDebug class - a set of debugging functions, that are not to be
// instantiated by the template.
//
struct PMDebug {
- // If compiled in debug mode, these functions can be enabled by setting
- // -debug-pass on the command line of the tool being used.
- //
- static void PrintPassStructure(Pass *P);
+ static void PerformPassStartupStuff(Pass *P) {
+ // If debugging is enabled, print out argument information...
+ if (PassDebugging >= Arguments) {
+ std::cerr << "Pass Arguments: ";
+ PrintArgumentInformation(P);
+ std::cerr << "\n";
+
+ // Print the pass execution structure
+ if (PassDebugging >= Structure)
+ P->dumpPassStructure();
+ }
+ }
+
+ static void PrintArgumentInformation(const Pass *P);
static void PrintPassInformation(unsigned,const char*,Pass *, Annotable *);
static void PrintAnalysisSetInfo(unsigned,const char*,Pass *P,
const std::vector<AnalysisID> &);
// 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 {
+ return UserTime+SystemTime < TR.UserTime+TR.SystemTime;
+ }
+
+ 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
// Output debug information...
- if (Parent == 0) PMDebug::PrintPassStructure(this);
+ if (Parent == 0) PMDebug::PerformPassStartupStuff(this);
// Run all of the passes
for (unsigned i = 0, e = Passes.size(); i < e; ++i) {
return 1 + Parent->getDepth();
}
+ virtual unsigned getNumContainedPasses() const { return Passes.size(); }
+ virtual const Pass *getContainedPass(unsigned N) const {
+ assert(N < Passes.size() && "Pass number out of range!");
+ return Passes[N];
+ }
+
// add - Add a pass to the queue of passes to run. This passes 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