Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: src/IceGlobalContext.h

Issue 887213002: Subzero: Fix stats collection and output for multithreading. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Use std::array Created 5 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/IceGlobalContext.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- subzero/src/IceGlobalContext.h - Global context defs -----*- C++ -*-===// 1 //===- subzero/src/IceGlobalContext.h - Global context defs -----*- C++ -*-===//
2 // 2 //
3 // The Subzero Code Generator 3 // The Subzero Code Generator
4 // 4 //
5 // This file is distributed under the University of Illinois Open Source 5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details. 6 // License. See LICENSE.TXT for details.
7 // 7 //
8 //===----------------------------------------------------------------------===// 8 //===----------------------------------------------------------------------===//
9 // 9 //
10 // This file declares aspects of the compilation that persist across 10 // This file declares aspects of the compilation that persist across
11 // multiple functions. 11 // multiple functions.
12 // 12 //
13 //===----------------------------------------------------------------------===// 13 //===----------------------------------------------------------------------===//
14 14
15 #ifndef SUBZERO_SRC_ICEGLOBALCONTEXT_H 15 #ifndef SUBZERO_SRC_ICEGLOBALCONTEXT_H
16 #define SUBZERO_SRC_ICEGLOBALCONTEXT_H 16 #define SUBZERO_SRC_ICEGLOBALCONTEXT_H
17 17
18 #include <array>
18 #include <mutex> 19 #include <mutex>
19 #include <thread> 20 #include <thread>
20 21
21 #include "IceDefs.h" 22 #include "IceDefs.h"
22 #include "IceClFlags.h" 23 #include "IceClFlags.h"
23 #include "IceIntrinsics.h" 24 #include "IceIntrinsics.h"
24 #include "IceRNG.h" 25 #include "IceRNG.h"
25 #include "IceTimerTree.h" 26 #include "IceTimerTree.h"
26 #include "IceTypes.h" 27 #include "IceTypes.h"
27 #include "IceUtils.h" 28 #include "IceUtils.h"
(...skipping 27 matching lines...) Expand all
55 }; 56 };
56 57
57 class GlobalContext { 58 class GlobalContext {
58 GlobalContext(const GlobalContext &) = delete; 59 GlobalContext(const GlobalContext &) = delete;
59 GlobalContext &operator=(const GlobalContext &) = delete; 60 GlobalContext &operator=(const GlobalContext &) = delete;
60 61
61 // CodeStats collects rudimentary statistics during translation. 62 // CodeStats collects rudimentary statistics during translation.
62 class CodeStats { 63 class CodeStats {
63 CodeStats(const CodeStats &) = delete; 64 CodeStats(const CodeStats &) = delete;
64 CodeStats &operator=(const CodeStats &) = default; 65 CodeStats &operator=(const CodeStats &) = default;
66 #define CODESTATS_TABLE \
67 /* dump string, enum value */ \
68 X("Inst Count ", InstCount) \
69 X("Regs Saved ", RegsSaved) \
70 X("Frame Bytes ", FrameByte) \
71 X("Spills ", NumSpills) \
72 X("Fills ", NumFills)
73 //#define X(str, tag)
65 74
66 public: 75 public:
67 CodeStats() 76 enum CSTag {
68 : InstructionsEmitted(0), RegistersSaved(0), FrameBytes(0), Spills(0), 77 #define X(str, tag) CS_##tag,
69 Fills(0) {} 78 CODESTATS_TABLE
70 void reset() { *this = CodeStats(); } 79 #undef X
71 void updateEmitted(uint32_t InstCount) { InstructionsEmitted += InstCount; } 80 CS_NUM
72 void updateRegistersSaved(uint32_t Num) { RegistersSaved += Num; } 81 };
73 void updateFrameBytes(uint32_t Bytes) { FrameBytes += Bytes; } 82 CodeStats() { reset(); }
74 void updateSpills() { ++Spills; } 83 void reset() { Stats.fill(0); }
75 void updateFills() { ++Fills; } 84 void update(CSTag Tag, uint32_t Count = 1) {
85 assert(Tag < Stats.size());
86 Stats[Tag] += Count;
87 }
88 void add(const CodeStats &Other) {
89 for (uint32_t i = 0; i < Stats.size(); ++i)
90 Stats[i] += Other.Stats[i];
91 }
76 void dump(const IceString &Name, Ostream &Str); 92 void dump(const IceString &Name, Ostream &Str);
77 93
78 private: 94 private:
79 uint32_t InstructionsEmitted; 95 std::array<uint32_t, CS_NUM> Stats;
80 uint32_t RegistersSaved;
81 uint32_t FrameBytes;
82 uint32_t Spills;
83 uint32_t Fills;
84 }; 96 };
85 97
86 // TimerList is a vector of TimerStack objects, with extra methods 98 // TimerList is a vector of TimerStack objects, with extra methods
87 // to initialize and merge these vectors. 99 // to initialize and merge these vectors.
88 class TimerList : public std::vector<TimerStack> { 100 class TimerList : public std::vector<TimerStack> {
89 public: 101 public:
90 // initInto() initializes a target list of timers based on the 102 // initInto() initializes a target list of timers based on the
91 // current list. In particular, it creates the same number of 103 // current list. In particular, it creates the same number of
92 // timers, in the same order, with the same names, but initially 104 // timers, in the same order, with the same names, but initially
93 // empty of timing data. 105 // empty of timing data.
(...skipping 20 matching lines...) Expand all
114 126
115 // ThreadContext contains thread-local data. This data can be 127 // ThreadContext contains thread-local data. This data can be
116 // combined/reduced as needed after all threads complete. 128 // combined/reduced as needed after all threads complete.
117 class ThreadContext { 129 class ThreadContext {
118 ThreadContext(const ThreadContext &) = delete; 130 ThreadContext(const ThreadContext &) = delete;
119 ThreadContext &operator=(const ThreadContext &) = delete; 131 ThreadContext &operator=(const ThreadContext &) = delete;
120 132
121 public: 133 public:
122 ThreadContext() {} 134 ThreadContext() {}
123 CodeStats StatsFunction; 135 CodeStats StatsFunction;
136 CodeStats StatsCumulative;
124 TimerList Timers; 137 TimerList Timers;
125 }; 138 };
126 139
127 public: 140 public:
128 GlobalContext(Ostream *OsDump, Ostream *OsEmit, ELFStreamer *ELFStreamer, 141 GlobalContext(Ostream *OsDump, Ostream *OsEmit, ELFStreamer *ELFStreamer,
129 VerboseMask Mask, TargetArch Arch, OptLevel Opt, 142 VerboseMask Mask, TargetArch Arch, OptLevel Opt,
130 IceString TestPrefix, const ClFlags &Flags); 143 IceString TestPrefix, const ClFlags &Flags);
131 ~GlobalContext(); 144 ~GlobalContext();
132 145
133 VerboseMask getVerbose() const { return VMask; } 146 VerboseMask getVerbose() const { return VMask; }
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 215
203 // Reset stats at the beginning of a function. 216 // Reset stats at the beginning of a function.
204 void resetStats() { 217 void resetStats() {
205 if (ALLOW_DUMP) 218 if (ALLOW_DUMP)
206 ICE_TLS_GET_FIELD(TLS)->StatsFunction.reset(); 219 ICE_TLS_GET_FIELD(TLS)->StatsFunction.reset();
207 } 220 }
208 void dumpStats(const IceString &Name, bool Final = false); 221 void dumpStats(const IceString &Name, bool Final = false);
209 void statsUpdateEmitted(uint32_t InstCount) { 222 void statsUpdateEmitted(uint32_t InstCount) {
210 if (!ALLOW_DUMP || !getFlags().DumpStats) 223 if (!ALLOW_DUMP || !getFlags().DumpStats)
211 return; 224 return;
212 ICE_TLS_GET_FIELD(TLS)->StatsFunction.updateEmitted(InstCount); 225 ThreadContext *TLS = ICE_TLS_GET_FIELD(TLS);
213 getStatsCumulative()->updateEmitted(InstCount); 226 TLS->StatsFunction.update(CodeStats::CS_InstCount, InstCount);
227 TLS->StatsCumulative.update(CodeStats::CS_InstCount, InstCount);
214 } 228 }
215 void statsUpdateRegistersSaved(uint32_t Num) { 229 void statsUpdateRegistersSaved(uint32_t Num) {
216 if (!ALLOW_DUMP || !getFlags().DumpStats) 230 if (!ALLOW_DUMP || !getFlags().DumpStats)
217 return; 231 return;
218 ICE_TLS_GET_FIELD(TLS)->StatsFunction.updateRegistersSaved(Num); 232 ThreadContext *TLS = ICE_TLS_GET_FIELD(TLS);
219 getStatsCumulative()->updateRegistersSaved(Num); 233 TLS->StatsFunction.update(CodeStats::CS_RegsSaved, Num);
234 TLS->StatsCumulative.update(CodeStats::CS_RegsSaved, Num);
220 } 235 }
221 void statsUpdateFrameBytes(uint32_t Bytes) { 236 void statsUpdateFrameBytes(uint32_t Bytes) {
222 if (!ALLOW_DUMP || !getFlags().DumpStats) 237 if (!ALLOW_DUMP || !getFlags().DumpStats)
223 return; 238 return;
224 ICE_TLS_GET_FIELD(TLS)->StatsFunction.updateFrameBytes(Bytes); 239 ThreadContext *TLS = ICE_TLS_GET_FIELD(TLS);
225 getStatsCumulative()->updateFrameBytes(Bytes); 240 TLS->StatsFunction.update(CodeStats::CS_FrameByte, Bytes);
241 TLS->StatsCumulative.update(CodeStats::CS_FrameByte, Bytes);
226 } 242 }
227 void statsUpdateSpills() { 243 void statsUpdateSpills() {
228 if (!ALLOW_DUMP || !getFlags().DumpStats) 244 if (!ALLOW_DUMP || !getFlags().DumpStats)
229 return; 245 return;
230 ICE_TLS_GET_FIELD(TLS)->StatsFunction.updateSpills(); 246 ThreadContext *TLS = ICE_TLS_GET_FIELD(TLS);
231 getStatsCumulative()->updateSpills(); 247 TLS->StatsFunction.update(CodeStats::CS_NumSpills);
248 TLS->StatsCumulative.update(CodeStats::CS_NumSpills);
232 } 249 }
233 void statsUpdateFills() { 250 void statsUpdateFills() {
234 if (!ALLOW_DUMP || !getFlags().DumpStats) 251 if (!ALLOW_DUMP || !getFlags().DumpStats)
235 return; 252 return;
236 ICE_TLS_GET_FIELD(TLS)->StatsFunction.updateFills(); 253 ThreadContext *TLS = ICE_TLS_GET_FIELD(TLS);
237 getStatsCumulative()->updateFills(); 254 TLS->StatsFunction.update(CodeStats::CS_NumFills);
255 TLS->StatsCumulative.update(CodeStats::CS_NumFills);
238 } 256 }
239 257
240 // These are predefined TimerStackIdT values. 258 // These are predefined TimerStackIdT values.
241 enum TimerStackKind { TSK_Default = 0, TSK_Funcs, TSK_Num }; 259 enum TimerStackKind { TSK_Default = 0, TSK_Funcs, TSK_Num };
242 260
243 // newTimerStackID() creates a new TimerStack in the global space. 261 // newTimerStackID() creates a new TimerStack in the global space.
244 // It does not affect any TimerStack objects in TLS. 262 // It does not affect any TimerStack objects in TLS.
245 TimerStackIdT newTimerStackID(const IceString &Name); 263 TimerStackIdT newTimerStackID(const IceString &Name);
246 // dumpTimers() dumps the global timer data. As such, one probably 264 // dumpTimers() dumps the global timer data. As such, one probably
247 // wants to call mergeTimerStacks() as a prerequisite. 265 // wants to call mergeTimerStacks() as a prerequisite.
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
289 for (std::thread &Worker : TranslationThreads) { 307 for (std::thread &Worker : TranslationThreads) {
290 Worker.join(); 308 Worker.join();
291 } 309 }
292 TranslationThreads.clear(); 310 TranslationThreads.clear();
293 // TODO(stichnot): join the emitter thread. 311 // TODO(stichnot): join the emitter thread.
294 if (ALLOW_DUMP) { 312 if (ALLOW_DUMP) {
295 auto Timers = getTimers(); 313 auto Timers = getTimers();
296 for (ThreadContext *TLS : AllThreadContexts) 314 for (ThreadContext *TLS : AllThreadContexts)
297 Timers->mergeFrom(TLS->Timers); 315 Timers->mergeFrom(TLS->Timers);
298 } 316 }
317 if (ALLOW_DUMP) {
318 // Do a separate loop over AllThreadContexts to avoid holding
319 // two locks at once.
320 auto Stats = getStatsCumulative();
321 for (ThreadContext *TLS : AllThreadContexts)
322 Stats->add(TLS->StatsCumulative);
323 }
299 } 324 }
300 325
301 // Translation thread startup routine. 326 // Translation thread startup routine.
302 void translateFunctionsWrapper(ThreadContext *MyTLS) { 327 void translateFunctionsWrapper(ThreadContext *MyTLS) {
303 ICE_TLS_SET_FIELD(TLS, MyTLS); 328 ICE_TLS_SET_FIELD(TLS, MyTLS);
304 translateFunctions(); 329 translateFunctions();
305 } 330 }
306 // Translate functions from the Cfg queue until the queue is empty. 331 // Translate functions from the Cfg queue until the queue is empty.
307 void translateFunctions(); 332 void translateFunctions();
308 333
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after
439 explicit OstreamLocker(GlobalContext *Ctx) : Ctx(Ctx) { Ctx->lockStr(); } 464 explicit OstreamLocker(GlobalContext *Ctx) : Ctx(Ctx) { Ctx->lockStr(); }
440 ~OstreamLocker() { Ctx->unlockStr(); } 465 ~OstreamLocker() { Ctx->unlockStr(); }
441 466
442 private: 467 private:
443 GlobalContext *const Ctx; 468 GlobalContext *const Ctx;
444 }; 469 };
445 470
446 } // end of namespace Ice 471 } // end of namespace Ice
447 472
448 #endif // SUBZERO_SRC_ICEGLOBALCONTEXT_H 473 #endif // SUBZERO_SRC_ICEGLOBALCONTEXT_H
OLDNEW
« no previous file with comments | « no previous file | src/IceGlobalContext.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698