Subzero: Rewrite the pass timing infrastructure.

This makes it much more useful for individual analysis and long-term translation performance tracking.

1. Collect and report aggregated across the entire translation, instead of function-by-function.  If you really care about a single function, just extract it and translate it separately for analysis.

2. Remove "-verbose time" and just use -timing.

3. Collects two kinds of timings: cumulative and flat.  Cumulative measures the total time, even if a callee also times itself.  Flat only measures the currently active timer at the top of the stack.  The flat times should add up to 100%, but cumulative will usually add up to much more than 100%.

BUG= none
R=jvoung@chromium.org

Review URL: https://codereview.chromium.org/610813002
diff --git a/src/IceGlobalContext.h b/src/IceGlobalContext.h
index f997b65..3c53773 100644
--- a/src/IceGlobalContext.h
+++ b/src/IceGlobalContext.h
@@ -69,12 +69,8 @@
 
   // Returns true if any of the specified options in the verbose mask
   // are set.  If the argument is omitted, it checks if any verbose
-  // options at all are set.  IceV_Timing is treated specially, so
-  // that running with just IceV_Timing verbosity doesn't trigger an
-  // avalanche of extra output.
-  bool isVerbose(VerboseMask Mask = (IceV_All & ~IceV_Timing)) const {
-    return VMask & Mask;
-  }
+  // options at all are set.
+  bool isVerbose(VerboseMask Mask = IceV_All) const { return VMask & Mask; }
   void setVerbose(VerboseMask Mask) { VMask = Mask; }
   void addVerbose(VerboseMask Mask) { VMask |= Mask; }
   void subVerbose(VerboseMask Mask) { VMask &= ~Mask; }
@@ -154,6 +150,11 @@
     StatsCumulative.updateFills();
   }
 
+  static TimerIdT getTimerID(const IceString &Name);
+  void pushTimer(TimerIdT ID);
+  void popTimer(TimerIdT ID);
+  void dumpTimers();
+
 private:
   Ostream *StrDump; // Stream for dumping / diagnostics
   Ostream *StrEmit; // Stream for code emission
@@ -170,6 +171,7 @@
   RandomNumberGenerator RNG;
   CodeStats StatsFunction;
   CodeStats StatsCumulative;
+  llvm::OwningPtr<class TimerStack> Timers;
   GlobalContext(const GlobalContext &) LLVM_DELETED_FUNCTION;
   GlobalContext &operator=(const GlobalContext &) LLVM_DELETED_FUNCTION;
 
@@ -178,6 +180,30 @@
   void incrementSubstitutions(ManglerVector &OldName) const;
 };
 
+// Helper class to push and pop a timer marker.  The constructor
+// pushes a marker, and the destructor pops it.  This is for
+// convenient timing of regions of code.
+class TimerMarker {
+  TimerMarker(const TimerMarker &) LLVM_DELETED_FUNCTION;
+  TimerMarker &operator=(const TimerMarker &) LLVM_DELETED_FUNCTION;
+
+public:
+  TimerMarker(TimerIdT ID, GlobalContext *Ctx)
+      : ID(ID), Ctx(Ctx), Active(Ctx->getFlags().SubzeroTimingEnabled) {
+    if (Active)
+      Ctx->pushTimer(ID);
+  }
+  ~TimerMarker() {
+    if (Active)
+      Ctx->popTimer(ID);
+  }
+
+private:
+  TimerIdT ID;
+  GlobalContext *const Ctx;
+  const bool Active;
+};
+
 } // end of namespace Ice
 
 #endif // SUBZERO_SRC_ICEGLOBALCONTEXT_H