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;