Chromium Code Reviews| Index: src/IceGlobalContext.cpp |
| diff --git a/src/IceGlobalContext.cpp b/src/IceGlobalContext.cpp |
| index d353bfe3874352d9ee789a218c84c5ab5a115634..189cca52120f306ab0039016f5f4ccc215aa7d65 100644 |
| --- a/src/IceGlobalContext.cpp |
| +++ b/src/IceGlobalContext.cpp |
| @@ -218,6 +218,37 @@ public: |
| UndefPool Undefs; |
| }; |
| +void GlobalContext::waitForWorkerThreads() { |
| + if (WaitForWorkerThreadsCalled.exchange(true)) |
| + return; |
| + optQueueNotifyEnd(); |
| + for (std::thread &Worker : TranslationThreads) { |
| + Worker.join(); |
| + } |
| + TranslationThreads.clear(); |
| + |
| + // Only notify the emit queue to end after all the translation threads have |
| + // ended. |
| + emitQueueNotifyEnd(); |
| + for (std::thread &Worker : EmitterThreads) { |
| + Worker.join(); |
| + } |
| + EmitterThreads.clear(); |
| + |
| + if (BuildDefs::timers()) { |
| + auto Timers = getTimers(); |
| + for (ThreadContext *TLS : AllThreadContexts) |
| + Timers->mergeFrom(TLS->Timers); |
| + } |
| + if (BuildDefs::dump()) { |
| + // Do a separate loop over AllThreadContexts to avoid holding two locks |
|
Jim Stichnoth
2016/03/31 16:08:08
reflow...
Karl
2016/03/31 16:33:49
Done.
|
| + // at once. |
| + auto Stats = getStatsCumulative(); |
| + for (ThreadContext *TLS : AllThreadContexts) |
| + Stats->add(TLS->StatsCumulative); |
| + } |
| +} |
| + |
| void GlobalContext::CodeStats::dump(const IceString &Name, GlobalContext *Ctx) { |
| if (!BuildDefs::dump()) |
| return; |
| @@ -254,9 +285,12 @@ void GlobalContext::CodeStats::dump(const IceString &Name, GlobalContext *Ctx) { |
| GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError, |
| ELFStreamer *ELFStr) |
| : ConstPool(new ConstantPool()), ErrorStatus(), StrDump(OsDump), |
| - StrEmit(OsEmit), StrError(OsError), ObjectWriter(), |
| - OptQ(/*Sequential=*/Flags.isSequential(), |
| - /*MaxSize=*/Flags.getNumTranslationThreads()), |
| + StrEmit(OsEmit), StrError(OsError), WaitForWorkerThreadsCalled(false), |
| + ObjectWriter(), OptQ(/*Sequential=*/Flags.isSequential(), |
| + /*MaxSize=*/ |
| + (Flags.getParseParallel() && Flags.getBuildOnRead()) |
| + ? MaxOptQSize |
| + : Flags.getNumTranslationThreads()), |
| // EmitQ is allowed unlimited size. |
| EmitQ(/*Sequential=*/Flags.isSequential()), |
| DataLowering(TargetDataLowering::createLowering(this)) { |
| @@ -309,7 +343,8 @@ GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError, |
| void GlobalContext::translateFunctions() { |
| TimerMarker Timer(TimerStack::TT_translateFunctions, this); |
| - while (std::unique_ptr<Cfg> Func = optQueueBlockingPop()) { |
| + while (std::unique_ptr<OptWorkItem> OptItem = optQueueBlockingPop()) { |
| + std::unique_ptr<Cfg> Func = OptItem->getParsedCfg(); |
|
John
2016/03/31 15:51:36
optional: auto
Karl
2016/03/31 16:33:49
Done.
|
| // Install Func in TLS for Cfg-specific container allocators. |
| CfgLocalAllocatorScope _(Func.get()); |
| // Reset per-function stats being accumulated in TLS. |
| @@ -867,19 +902,19 @@ void GlobalContext::setTimerName(TimerStackIdT StackID, |
| // interface to take and transfer ownership, but they internally store the raw |
| // Cfg pointer in the work queue. This allows e.g. future queue optimizations |
| // such as the use of atomics to modify queue elements. |
| -void GlobalContext::optQueueBlockingPush(std::unique_ptr<Cfg> Func) { |
| - assert(Func); |
| +void GlobalContext::optQueueBlockingPush(std::unique_ptr<OptWorkItem> Item) { |
| + assert(Item); |
| { |
| TimerMarker _(TimerStack::TT_qTransPush, this); |
| - OptQ.blockingPush(std::move(Func)); |
| + OptQ.blockingPush(std::move(Item)); |
| } |
| if (getFlags().isSequential()) |
| translateFunctions(); |
| } |
| -std::unique_ptr<Cfg> GlobalContext::optQueueBlockingPop() { |
| +std::unique_ptr<OptWorkItem> GlobalContext::optQueueBlockingPop() { |
| TimerMarker _(TimerStack::TT_qTransPop, this); |
| - return std::unique_ptr<Cfg>(OptQ.blockingPop()); |
| + return std::unique_ptr<OptWorkItem>(OptQ.blockingPop()); |
| } |
| void GlobalContext::emitQueueBlockingPush( |