Subzero: Refine the memory usage report with -szstats .

The problem is that the memory usage that comes from the -track-memory option is not very well-defined (it's a hidden LLVM option after all).  It gives an OK sense of memory growth over time, but sometimes we really want to know how much CFG-local arena memory was allocated for a particular function.

To help with this, we add another row to the stats output, giving the MB size of the CFG arena at the end of translating the method.

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

Review URL: https://codereview.chromium.org/1848733002 .
diff --git a/src/IceCompiler.cpp b/src/IceCompiler.cpp
index 08ce5a5..7a426fc 100644
--- a/src/IceCompiler.cpp
+++ b/src/IceCompiler.cpp
@@ -144,8 +144,7 @@
     constexpr bool NoDumpCumulative = false;
     Ctx.dumpTimers(GlobalContext::TSK_Funcs, NoDumpCumulative);
   }
-  constexpr bool FinalStats = true;
-  Ctx.dumpStats("_FINAL_", FinalStats);
+  Ctx.dumpStats();
 }
 
 } // end of namespace Ice
diff --git a/src/IceGlobalContext.cpp b/src/IceGlobalContext.cpp
index fdfe008..eb71df1 100644
--- a/src/IceGlobalContext.cpp
+++ b/src/IceGlobalContext.cpp
@@ -244,12 +244,13 @@
   }
 }
 
-void GlobalContext::CodeStats::dump(const std::string &Name,
-                                    GlobalContext *Ctx) {
+void GlobalContext::CodeStats::dump(const Cfg *Func, GlobalContext *Ctx) {
   if (!BuildDefs::dump())
     return;
   OstreamLocker _(Ctx);
   Ostream &Str = Ctx->getStrDump();
+  const std::string Name =
+      (Func == nullptr ? "_FINAL_" : Func->getFunctionNameAndSize());
 #define X(str, tag)                                                            \
   Str << "|" << Name << "|" str "|" << Stats[CS_##tag] << "\n";
   CODESTATS_TABLE
@@ -276,6 +277,10 @@
     Str << "|ExtRel=" << Pool->ExternRelocatables.size();
   }
   Str << "\n";
+  if (Func != nullptr) {
+    Str << "|" << Name << "|Cfg Memory  |" << Func->getTotalMemoryMB()
+        << " MB\n";
+  }
 }
 
 GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError,
@@ -380,7 +385,7 @@
         // stats have been fully collected into this thread's TLS.
         // Dump them before TLS is reset for the next Cfg.
         if (BuildDefs::dump())
-          dumpStats(Func->getFunctionNameAndSize());
+          dumpStats(Func.get());
         auto Asm = Func->releaseAssembler();
         // Copy relevant fields into Asm before Func is deleted.
         Asm->setFunctionName(Func->getFunctionName());
@@ -634,7 +639,7 @@
         // differently-typed copy.
         CfgLocalAllocatorScope _(Func.get());
         Func->emit();
-        dumpStats(Func->getFunctionNameAndSize());
+        dumpStats(Func.get());
       } break;
       }
     }
@@ -944,13 +949,13 @@
   return EmitQ.blockingPop();
 }
 
-void GlobalContext::dumpStats(const std::string &Name, bool Final) {
+void GlobalContext::dumpStats(const Cfg *Func) {
   if (!getFlags().getDumpStats())
     return;
-  if (Final) {
-    getStatsCumulative()->dump(Name, this);
+  if (Func == nullptr) {
+    getStatsCumulative()->dump(Func, this);
   } else {
-    ICE_TLS_GET_FIELD(TLS)->StatsFunction.dump(Name, this);
+    ICE_TLS_GET_FIELD(TLS)->StatsFunction.dump(Func, this);
   }
 }
 
diff --git a/src/IceGlobalContext.h b/src/IceGlobalContext.h
index 3937b2a..5d27f5d 100644
--- a/src/IceGlobalContext.h
+++ b/src/IceGlobalContext.h
@@ -106,7 +106,9 @@
       for (uint32_t i = 0; i < Stats.size(); ++i)
         Stats[i] += Other.Stats[i];
     }
-    void dump(const std::string &Name, GlobalContext *Ctx);
+    /// Dumps the stats for the given Cfg.  If Func==nullptr, it identifies it
+    /// as the "final" cumulative stats instead as a specific function's name.
+    void dump(const Cfg *Func, GlobalContext *Ctx);
 
   private:
     std::array<uint32_t, CS_NUM> Stats;
@@ -301,7 +303,7 @@
     if (BuildDefs::dump())
       ICE_TLS_GET_FIELD(TLS)->StatsFunction.reset();
   }
-  void dumpStats(const std::string &Name, bool Final = false);
+  void dumpStats(const Cfg *Func = nullptr);
   void statsUpdateEmitted(uint32_t InstCount) {
     if (!getFlags().getDumpStats())
       return;