OLD | NEW |
---|---|
1 //===- subzero/src/IceGlobalContext.cpp - Global context defs -------------===// | 1 //===- subzero/src/IceGlobalContext.cpp - Global context defs -------------===// |
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 /// \file | 10 /// \file |
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
211 TypePool<IceType_i8, int8_t, ConstantInteger32> Integers8; | 211 TypePool<IceType_i8, int8_t, ConstantInteger32> Integers8; |
212 TypePool<IceType_i16, int16_t, ConstantInteger32> Integers16; | 212 TypePool<IceType_i16, int16_t, ConstantInteger32> Integers16; |
213 TypePool<IceType_i32, int32_t, ConstantInteger32> Integers32; | 213 TypePool<IceType_i32, int32_t, ConstantInteger32> Integers32; |
214 TypePool<IceType_i64, int64_t, ConstantInteger64> Integers64; | 214 TypePool<IceType_i64, int64_t, ConstantInteger64> Integers64; |
215 TypePool<IceType_i32, RelocatableTuple, ConstantRelocatable> Relocatables; | 215 TypePool<IceType_i32, RelocatableTuple, ConstantRelocatable> Relocatables; |
216 TypePool<IceType_i32, RelocatableTuple, ConstantRelocatable> | 216 TypePool<IceType_i32, RelocatableTuple, ConstantRelocatable> |
217 ExternRelocatables; | 217 ExternRelocatables; |
218 UndefPool Undefs; | 218 UndefPool Undefs; |
219 }; | 219 }; |
220 | 220 |
221 void GlobalContext::waitForWorkerThreads() { | |
222 { // Make sure we wait at most once. | |
223 std::unique_lock<GlobalLockType> L(WaitForWorkersLock); | |
Jim Stichnoth
2016/03/25 04:31:04
Our new super-awesome coding style would name this
Karl
2016/03/29 17:35:02
Removed, went with atomic_bool.
| |
224 if (WaitForWorkerThreadsCalled) | |
Jim Stichnoth
2016/03/25 04:31:04
It seems that WaitForWorkerThreadsCalled could act
Karl
2016/03/29 17:35:02
Changed to atomic_bool.
| |
225 return; | |
226 WaitForWorkerThreadsCalled = true; | |
227 } | |
228 optQueueNotifyEnd(); | |
229 for (std::thread &Worker : TranslationThreads) { | |
230 Worker.join(); | |
231 } | |
232 TranslationThreads.clear(); | |
233 | |
234 // Only notify the emit queue to end after all the translation threads have | |
235 // ended. | |
236 emitQueueNotifyEnd(); | |
237 for (std::thread &Worker : EmitterThreads) { | |
238 Worker.join(); | |
239 } | |
240 EmitterThreads.clear(); | |
241 | |
242 if (BuildDefs::timers()) { | |
243 auto Timers = getTimers(); | |
244 for (ThreadContext *TLS : AllThreadContexts) | |
245 Timers->mergeFrom(TLS->Timers); | |
246 } | |
247 if (BuildDefs::dump()) { | |
248 // Do a separate loop over AllThreadContexts to avoid holding two locks | |
249 // at once. | |
250 auto Stats = getStatsCumulative(); | |
251 for (ThreadContext *TLS : AllThreadContexts) | |
252 Stats->add(TLS->StatsCumulative); | |
253 } | |
254 } | |
255 | |
221 void GlobalContext::CodeStats::dump(const IceString &Name, GlobalContext *Ctx) { | 256 void GlobalContext::CodeStats::dump(const IceString &Name, GlobalContext *Ctx) { |
222 if (!BuildDefs::dump()) | 257 if (!BuildDefs::dump()) |
223 return; | 258 return; |
224 OstreamLocker _(Ctx); | 259 OstreamLocker _(Ctx); |
225 Ostream &Str = Ctx->getStrDump(); | 260 Ostream &Str = Ctx->getStrDump(); |
226 #define X(str, tag) \ | 261 #define X(str, tag) \ |
227 Str << "|" << Name << "|" str "|" << Stats[CS_##tag] << "\n"; | 262 Str << "|" << Name << "|" str "|" << Stats[CS_##tag] << "\n"; |
228 CODESTATS_TABLE | 263 CODESTATS_TABLE |
229 #undef X | 264 #undef X |
230 Str << "|" << Name << "|Spills+Fills|" | 265 Str << "|" << Name << "|Spills+Fills|" |
(...skipping 18 matching lines...) Expand all Loading... | |
249 Str << "|ExtRel=" << Pool->ExternRelocatables.size(); | 284 Str << "|ExtRel=" << Pool->ExternRelocatables.size(); |
250 } | 285 } |
251 Str << "\n"; | 286 Str << "\n"; |
252 } | 287 } |
253 | 288 |
254 GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError, | 289 GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError, |
255 ELFStreamer *ELFStr) | 290 ELFStreamer *ELFStr) |
256 : ConstPool(new ConstantPool()), ErrorStatus(), StrDump(OsDump), | 291 : ConstPool(new ConstantPool()), ErrorStatus(), StrDump(OsDump), |
257 StrEmit(OsEmit), StrError(OsError), ObjectWriter(), | 292 StrEmit(OsEmit), StrError(OsError), ObjectWriter(), |
258 OptQ(/*Sequential=*/Flags.isSequential(), | 293 OptQ(/*Sequential=*/Flags.isSequential(), |
259 /*MaxSize=*/Flags.getNumTranslationThreads()), | 294 /*MaxSize=*/ |
295 (Flags.getParseParallel() && Flags.getBuildOnRead()) | |
296 ? MaxOptQSize | |
297 : Flags.getNumTranslationThreads()), | |
260 // EmitQ is allowed unlimited size. | 298 // EmitQ is allowed unlimited size. |
261 EmitQ(/*Sequential=*/Flags.isSequential()), | 299 EmitQ(/*Sequential=*/Flags.isSequential()), |
262 DataLowering(TargetDataLowering::createLowering(this)) { | 300 DataLowering(TargetDataLowering::createLowering(this)) { |
263 assert(OsDump && "OsDump is not defined for GlobalContext"); | 301 assert(OsDump && "OsDump is not defined for GlobalContext"); |
264 assert(OsEmit && "OsEmit is not defined for GlobalContext"); | 302 assert(OsEmit && "OsEmit is not defined for GlobalContext"); |
265 assert(OsError && "OsError is not defined for GlobalContext"); | 303 assert(OsError && "OsError is not defined for GlobalContext"); |
266 // Make sure thread_local fields are properly initialized before any | 304 // Make sure thread_local fields are properly initialized before any |
267 // accesses are made. Do this here instead of at the start of | 305 // accesses are made. Do this here instead of at the start of |
268 // main() so that all clients (e.g. unit tests) can benefit for | 306 // main() so that all clients (e.g. unit tests) can benefit for |
269 // free. | 307 // free. |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
302 RuntimeHelperFunc[static_cast<size_t>(RuntimeHelper::H_##Tag)] = \ | 340 RuntimeHelperFunc[static_cast<size_t>(RuntimeHelper::H_##Tag)] = \ |
303 getConstantExternSym(Name); | 341 getConstantExternSym(Name); |
304 RUNTIME_HELPER_FUNCTIONS_TABLE | 342 RUNTIME_HELPER_FUNCTIONS_TABLE |
305 #undef X | 343 #undef X |
306 | 344 |
307 TargetLowering::staticInit(this); | 345 TargetLowering::staticInit(this); |
308 } | 346 } |
309 | 347 |
310 void GlobalContext::translateFunctions() { | 348 void GlobalContext::translateFunctions() { |
311 TimerMarker Timer(TimerStack::TT_translateFunctions, this); | 349 TimerMarker Timer(TimerStack::TT_translateFunctions, this); |
312 while (std::unique_ptr<Cfg> Func = optQueueBlockingPop()) { | 350 while (std::unique_ptr<OptWorkItem> OptItem = optQueueBlockingPop()) { |
351 std::unique_ptr<Cfg> Func = OptItem->getParsedCfg(); | |
313 // Install Func in TLS for Cfg-specific container allocators. | 352 // Install Func in TLS for Cfg-specific container allocators. |
314 CfgLocalAllocatorScope _(Func.get()); | 353 CfgLocalAllocatorScope _(Func.get()); |
315 // Reset per-function stats being accumulated in TLS. | 354 // Reset per-function stats being accumulated in TLS. |
316 resetStats(); | 355 resetStats(); |
317 // Set verbose level to none if the current function does NOT | 356 // Set verbose level to none if the current function does NOT |
318 // match the -verbose-focus command-line option. | 357 // match the -verbose-focus command-line option. |
319 if (!matchSymbolName(Func->getFunctionName(), | 358 if (!matchSymbolName(Func->getFunctionName(), |
320 getFlags().getVerboseFocusOn())) | 359 getFlags().getVerboseFocusOn())) |
321 Func->setVerbose(IceV_None); | 360 Func->setVerbose(IceV_None); |
322 // Disable translation if -notranslate is specified, or if the | 361 // Disable translation if -notranslate is specified, or if the |
(...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
860 const IceString &NewName) { | 899 const IceString &NewName) { |
861 auto Timers = &ICE_TLS_GET_FIELD(TLS)->Timers; | 900 auto Timers = &ICE_TLS_GET_FIELD(TLS)->Timers; |
862 assert(StackID < Timers->size()); | 901 assert(StackID < Timers->size()); |
863 Timers->at(StackID).setName(NewName); | 902 Timers->at(StackID).setName(NewName); |
864 } | 903 } |
865 | 904 |
866 // Note: optQueueBlockingPush and optQueueBlockingPop use unique_ptr at the | 905 // Note: optQueueBlockingPush and optQueueBlockingPop use unique_ptr at the |
867 // interface to take and transfer ownership, but they internally store the raw | 906 // interface to take and transfer ownership, but they internally store the raw |
868 // Cfg pointer in the work queue. This allows e.g. future queue optimizations | 907 // Cfg pointer in the work queue. This allows e.g. future queue optimizations |
869 // such as the use of atomics to modify queue elements. | 908 // such as the use of atomics to modify queue elements. |
870 void GlobalContext::optQueueBlockingPush(std::unique_ptr<Cfg> Func) { | 909 void GlobalContext::optQueueBlockingPush(std::unique_ptr<OptWorkItem> Item) { |
871 assert(Func); | 910 assert(Item); |
872 { | 911 { |
873 TimerMarker _(TimerStack::TT_qTransPush, this); | 912 TimerMarker _(TimerStack::TT_qTransPush, this); |
874 OptQ.blockingPush(std::move(Func)); | 913 OptQ.blockingPush(std::move(Item)); |
875 } | 914 } |
876 if (getFlags().isSequential()) | 915 if (getFlags().isSequential()) |
877 translateFunctions(); | 916 translateFunctions(); |
878 } | 917 } |
879 | 918 |
880 std::unique_ptr<Cfg> GlobalContext::optQueueBlockingPop() { | 919 std::unique_ptr<OptWorkItem> GlobalContext::optQueueBlockingPop() { |
881 TimerMarker _(TimerStack::TT_qTransPop, this); | 920 TimerMarker _(TimerStack::TT_qTransPop, this); |
882 return std::unique_ptr<Cfg>(OptQ.blockingPop()); | 921 return std::unique_ptr<OptWorkItem>(OptQ.blockingPop()); |
883 } | 922 } |
884 | 923 |
885 void GlobalContext::emitQueueBlockingPush( | 924 void GlobalContext::emitQueueBlockingPush( |
886 std::unique_ptr<EmitterWorkItem> Item) { | 925 std::unique_ptr<EmitterWorkItem> Item) { |
887 assert(Item); | 926 assert(Item); |
888 { | 927 { |
889 TimerMarker _(TimerStack::TT_qEmitPush, this); | 928 TimerMarker _(TimerStack::TT_qEmitPush, this); |
890 EmitQ.blockingPush(std::move(Item)); | 929 EmitQ.blockingPush(std::move(Item)); |
891 } | 930 } |
892 if (getFlags().isSequential()) | 931 if (getFlags().isSequential()) |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
947 Ctx = Func->getContext(); | 986 Ctx = Func->getContext(); |
948 Active = | 987 Active = |
949 Func->getFocusedTiming() || Ctx->getFlags().getSubzeroTimingEnabled(); | 988 Func->getFocusedTiming() || Ctx->getFlags().getSubzeroTimingEnabled(); |
950 if (Active) | 989 if (Active) |
951 Ctx->pushTimer(ID, StackID); | 990 Ctx->pushTimer(ID, StackID); |
952 } | 991 } |
953 | 992 |
954 ICE_TLS_DEFINE_FIELD(GlobalContext::ThreadContext *, GlobalContext, TLS); | 993 ICE_TLS_DEFINE_FIELD(GlobalContext::ThreadContext *, GlobalContext, TLS); |
955 | 994 |
956 } // end of namespace Ice | 995 } // end of namespace Ice |
OLD | NEW |