Commit b5eee3d7 by Jim Stichnoth

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 .
parent e8457a26
...@@ -144,8 +144,7 @@ void Compiler::run(const Ice::ClFlags &Flags, GlobalContext &Ctx, ...@@ -144,8 +144,7 @@ void Compiler::run(const Ice::ClFlags &Flags, GlobalContext &Ctx,
constexpr bool NoDumpCumulative = false; constexpr bool NoDumpCumulative = false;
Ctx.dumpTimers(GlobalContext::TSK_Funcs, NoDumpCumulative); Ctx.dumpTimers(GlobalContext::TSK_Funcs, NoDumpCumulative);
} }
constexpr bool FinalStats = true; Ctx.dumpStats();
Ctx.dumpStats("_FINAL_", FinalStats);
} }
} // end of namespace Ice } // end of namespace Ice
...@@ -244,12 +244,13 @@ void GlobalContext::waitForWorkerThreads() { ...@@ -244,12 +244,13 @@ void GlobalContext::waitForWorkerThreads() {
} }
} }
void GlobalContext::CodeStats::dump(const std::string &Name, void GlobalContext::CodeStats::dump(const Cfg *Func, GlobalContext *Ctx) {
GlobalContext *Ctx) {
if (!BuildDefs::dump()) if (!BuildDefs::dump())
return; return;
OstreamLocker _(Ctx); OstreamLocker _(Ctx);
Ostream &Str = Ctx->getStrDump(); Ostream &Str = Ctx->getStrDump();
const std::string Name =
(Func == nullptr ? "_FINAL_" : Func->getFunctionNameAndSize());
#define X(str, tag) \ #define X(str, tag) \
Str << "|" << Name << "|" str "|" << Stats[CS_##tag] << "\n"; Str << "|" << Name << "|" str "|" << Stats[CS_##tag] << "\n";
CODESTATS_TABLE CODESTATS_TABLE
...@@ -276,6 +277,10 @@ void GlobalContext::CodeStats::dump(const std::string &Name, ...@@ -276,6 +277,10 @@ void GlobalContext::CodeStats::dump(const std::string &Name,
Str << "|ExtRel=" << Pool->ExternRelocatables.size(); Str << "|ExtRel=" << Pool->ExternRelocatables.size();
} }
Str << "\n"; Str << "\n";
if (Func != nullptr) {
Str << "|" << Name << "|Cfg Memory |" << Func->getTotalMemoryMB()
<< " MB\n";
}
} }
GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError, GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError,
...@@ -380,7 +385,7 @@ void GlobalContext::translateFunctions() { ...@@ -380,7 +385,7 @@ void GlobalContext::translateFunctions() {
// stats have been fully collected into this thread's TLS. // stats have been fully collected into this thread's TLS.
// Dump them before TLS is reset for the next Cfg. // Dump them before TLS is reset for the next Cfg.
if (BuildDefs::dump()) if (BuildDefs::dump())
dumpStats(Func->getFunctionNameAndSize()); dumpStats(Func.get());
auto Asm = Func->releaseAssembler(); auto Asm = Func->releaseAssembler();
// Copy relevant fields into Asm before Func is deleted. // Copy relevant fields into Asm before Func is deleted.
Asm->setFunctionName(Func->getFunctionName()); Asm->setFunctionName(Func->getFunctionName());
...@@ -634,7 +639,7 @@ void GlobalContext::emitItems() { ...@@ -634,7 +639,7 @@ void GlobalContext::emitItems() {
// differently-typed copy. // differently-typed copy.
CfgLocalAllocatorScope _(Func.get()); CfgLocalAllocatorScope _(Func.get());
Func->emit(); Func->emit();
dumpStats(Func->getFunctionNameAndSize()); dumpStats(Func.get());
} break; } break;
} }
} }
...@@ -944,13 +949,13 @@ std::unique_ptr<EmitterWorkItem> GlobalContext::emitQueueBlockingPop() { ...@@ -944,13 +949,13 @@ std::unique_ptr<EmitterWorkItem> GlobalContext::emitQueueBlockingPop() {
return EmitQ.blockingPop(); return EmitQ.blockingPop();
} }
void GlobalContext::dumpStats(const std::string &Name, bool Final) { void GlobalContext::dumpStats(const Cfg *Func) {
if (!getFlags().getDumpStats()) if (!getFlags().getDumpStats())
return; return;
if (Final) { if (Func == nullptr) {
getStatsCumulative()->dump(Name, this); getStatsCumulative()->dump(Func, this);
} else { } else {
ICE_TLS_GET_FIELD(TLS)->StatsFunction.dump(Name, this); ICE_TLS_GET_FIELD(TLS)->StatsFunction.dump(Func, this);
} }
} }
......
...@@ -106,7 +106,9 @@ class GlobalContext { ...@@ -106,7 +106,9 @@ class GlobalContext {
for (uint32_t i = 0; i < Stats.size(); ++i) for (uint32_t i = 0; i < Stats.size(); ++i)
Stats[i] += Other.Stats[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: private:
std::array<uint32_t, CS_NUM> Stats; std::array<uint32_t, CS_NUM> Stats;
...@@ -301,7 +303,7 @@ public: ...@@ -301,7 +303,7 @@ public:
if (BuildDefs::dump()) if (BuildDefs::dump())
ICE_TLS_GET_FIELD(TLS)->StatsFunction.reset(); 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) { void statsUpdateEmitted(uint32_t InstCount) {
if (!getFlags().getDumpStats()) if (!getFlags().getDumpStats())
return; return;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment