Subzero: Improve the use of timers.

Several things are done here:

1. Move timer support to be guarded by the ALLOW_TIMERS define, or the BuildDefs::timers() constexpr method.

2. Add a NODUMP build configuration to control whether dump support is built in.  So "make -f Makefile.standalone NODUMP=1 NOASSERT=1" is pretty close to a MINIMAL build with timer support.

3. Add some missing timers: alloca analysis, RMW analysis, helper call pre-lowering, load optimization analysis.  These omitted pass timings were being rolled up into the "O2" bucket.

4. Add timers around push and pop operations on the translate queue and the emit queue.

5. Refactor the clumsy code to push/pop function timers (as opposed to pass timers), so that it fits into the nice RAII TimerMarker class like the pass timers.

6. It turns out that even with MINIMAL or NODUMP builds, we still construct a longish std::string every time Cfg::dump() is called, even though the string isn't used in MINIMAL/NODUMP mode.  The dump() arg might as well be a const char * arg instead.

BUG= https://bugs.chromium.org/p/nativeclient/issues/detail?id=4360
R=kschimpf@google.com

Review URL: https://codereview.chromium.org/1784243006 .
diff --git a/src/IceCfg.cpp b/src/IceCfg.cpp
index a44e6b3..c3d91e6 100644
--- a/src/IceCfg.cpp
+++ b/src/IceCfg.cpp
@@ -187,9 +187,6 @@
 void Cfg::translate() {
   if (hasError())
     return;
-  // FunctionTimer conditionally pushes/pops a TimerMarker if TimeEachFunction
-  // is enabled.
-  std::unique_ptr<TimerMarker> FunctionTimer;
   if (BuildDefs::dump()) {
     const IceString &TimingFocusOn =
         getContext()->getFlags().getTimingFocusOn();
@@ -199,15 +196,12 @@
       getContext()->resetTimer(GlobalContext::TSK_Default);
       getContext()->setTimerName(GlobalContext::TSK_Default, Name);
     }
-    if (getContext()->getFlags().getTimeEachFunction())
-      FunctionTimer.reset(new TimerMarker(
-          getContext()->getTimerID(GlobalContext::TSK_Funcs, Name),
-          getContext(), GlobalContext::TSK_Funcs));
     if (isVerbose(IceV_Status)) {
       getContext()->getStrDump() << ">>>Translating "
                                  << getFunctionNameAndSize() << "\n";
     }
   }
+  TimerMarker T_func(getContext(), getFunctionName());
   TimerMarker T(TimerStack::TT_translate, this);
 
   dump("Initial CFG");
@@ -573,6 +567,7 @@
 }
 
 void Cfg::processAllocas(bool SortAndCombine) {
+  TimerMarker _(TimerStack::TT_alloca, this);
   const uint32_t StackAlignment = getTarget()->getStackAlignment();
   CfgNode *EntryNode = getEntryNode();
   // LLVM enforces power of 2 alignment.
@@ -1083,14 +1078,14 @@
 }
 
 // Dumps the IR with an optional introductory message.
-void Cfg::dump(const IceString &Message) {
+void Cfg::dump(const char *Message) {
   if (!BuildDefs::dump())
     return;
   if (!isVerbose())
     return;
   OstreamLocker L(Ctx);
   Ostream &Str = Ctx->getStrDump();
-  if (!Message.empty())
+  if (Message[0])
     Str << "================ " << Message << " ================\n";
   if (isVerbose(IceV_Mem)) {
     Str << "Memory size = " << getTotalMemoryMB() << " MB\n";