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 if (WaitForWorkerThreadsCalled.exchange(true)) | |
223 return; | |
224 optQueueNotifyEnd(); | |
225 for (std::thread &Worker : TranslationThreads) { | |
226 Worker.join(); | |
227 } | |
228 TranslationThreads.clear(); | |
229 | |
230 // Only notify the emit queue to end after all the translation threads have | |
231 // ended. | |
232 emitQueueNotifyEnd(); | |
233 for (std::thread &Worker : EmitterThreads) { | |
234 Worker.join(); | |
235 } | |
236 EmitterThreads.clear(); | |
237 | |
238 if (BuildDefs::timers()) { | |
239 auto Timers = getTimers(); | |
240 for (ThreadContext *TLS : AllThreadContexts) | |
241 Timers->mergeFrom(TLS->Timers); | |
242 } | |
243 if (BuildDefs::dump()) { | |
244 // 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.
| |
245 // at once. | |
246 auto Stats = getStatsCumulative(); | |
247 for (ThreadContext *TLS : AllThreadContexts) | |
248 Stats->add(TLS->StatsCumulative); | |
249 } | |
250 } | |
251 | |
221 void GlobalContext::CodeStats::dump(const IceString &Name, GlobalContext *Ctx) { | 252 void GlobalContext::CodeStats::dump(const IceString &Name, GlobalContext *Ctx) { |
222 if (!BuildDefs::dump()) | 253 if (!BuildDefs::dump()) |
223 return; | 254 return; |
224 OstreamLocker _(Ctx); | 255 OstreamLocker _(Ctx); |
225 Ostream &Str = Ctx->getStrDump(); | 256 Ostream &Str = Ctx->getStrDump(); |
226 #define X(str, tag) \ | 257 #define X(str, tag) \ |
227 Str << "|" << Name << "|" str "|" << Stats[CS_##tag] << "\n"; | 258 Str << "|" << Name << "|" str "|" << Stats[CS_##tag] << "\n"; |
228 CODESTATS_TABLE | 259 CODESTATS_TABLE |
229 #undef X | 260 #undef X |
230 Str << "|" << Name << "|Spills+Fills|" | 261 Str << "|" << Name << "|Spills+Fills|" |
(...skipping 16 matching lines...) Expand all Loading... | |
247 Str << "|i64=" << Pool->Integers64.size(); | 278 Str << "|i64=" << Pool->Integers64.size(); |
248 Str << "|Rel=" << Pool->Relocatables.size(); | 279 Str << "|Rel=" << Pool->Relocatables.size(); |
249 Str << "|ExtRel=" << Pool->ExternRelocatables.size(); | 280 Str << "|ExtRel=" << Pool->ExternRelocatables.size(); |
250 } | 281 } |
251 Str << "\n"; | 282 Str << "\n"; |
252 } | 283 } |
253 | 284 |
254 GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError, | 285 GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError, |
255 ELFStreamer *ELFStr) | 286 ELFStreamer *ELFStr) |
256 : ConstPool(new ConstantPool()), ErrorStatus(), StrDump(OsDump), | 287 : ConstPool(new ConstantPool()), ErrorStatus(), StrDump(OsDump), |
257 StrEmit(OsEmit), StrError(OsError), ObjectWriter(), | 288 StrEmit(OsEmit), StrError(OsError), WaitForWorkerThreadsCalled(false), |
258 OptQ(/*Sequential=*/Flags.isSequential(), | 289 ObjectWriter(), OptQ(/*Sequential=*/Flags.isSequential(), |
259 /*MaxSize=*/Flags.getNumTranslationThreads()), | 290 /*MaxSize=*/ |
291 (Flags.getParseParallel() && Flags.getBuildOnRead()) | |
292 ? MaxOptQSize | |
293 : Flags.getNumTranslationThreads()), | |
260 // EmitQ is allowed unlimited size. | 294 // EmitQ is allowed unlimited size. |
261 EmitQ(/*Sequential=*/Flags.isSequential()), | 295 EmitQ(/*Sequential=*/Flags.isSequential()), |
262 DataLowering(TargetDataLowering::createLowering(this)) { | 296 DataLowering(TargetDataLowering::createLowering(this)) { |
263 assert(OsDump && "OsDump is not defined for GlobalContext"); | 297 assert(OsDump && "OsDump is not defined for GlobalContext"); |
264 assert(OsEmit && "OsEmit is not defined for GlobalContext"); | 298 assert(OsEmit && "OsEmit is not defined for GlobalContext"); |
265 assert(OsError && "OsError is not defined for GlobalContext"); | 299 assert(OsError && "OsError is not defined for GlobalContext"); |
266 // Make sure thread_local fields are properly initialized before any | 300 // Make sure thread_local fields are properly initialized before any |
267 // accesses are made. Do this here instead of at the start of | 301 // 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 | 302 // main() so that all clients (e.g. unit tests) can benefit for |
269 // free. | 303 // free. |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
302 RuntimeHelperFunc[static_cast<size_t>(RuntimeHelper::H_##Tag)] = \ | 336 RuntimeHelperFunc[static_cast<size_t>(RuntimeHelper::H_##Tag)] = \ |
303 getConstantExternSym(Name); | 337 getConstantExternSym(Name); |
304 RUNTIME_HELPER_FUNCTIONS_TABLE | 338 RUNTIME_HELPER_FUNCTIONS_TABLE |
305 #undef X | 339 #undef X |
306 | 340 |
307 TargetLowering::staticInit(this); | 341 TargetLowering::staticInit(this); |
308 } | 342 } |
309 | 343 |
310 void GlobalContext::translateFunctions() { | 344 void GlobalContext::translateFunctions() { |
311 TimerMarker Timer(TimerStack::TT_translateFunctions, this); | 345 TimerMarker Timer(TimerStack::TT_translateFunctions, this); |
312 while (std::unique_ptr<Cfg> Func = optQueueBlockingPop()) { | 346 while (std::unique_ptr<OptWorkItem> OptItem = optQueueBlockingPop()) { |
347 std::unique_ptr<Cfg> Func = OptItem->getParsedCfg(); | |
John
2016/03/31 15:51:36
optional: auto
Karl
2016/03/31 16:33:49
Done.
| |
313 // Install Func in TLS for Cfg-specific container allocators. | 348 // Install Func in TLS for Cfg-specific container allocators. |
314 CfgLocalAllocatorScope _(Func.get()); | 349 CfgLocalAllocatorScope _(Func.get()); |
315 // Reset per-function stats being accumulated in TLS. | 350 // Reset per-function stats being accumulated in TLS. |
316 resetStats(); | 351 resetStats(); |
317 // Set verbose level to none if the current function does NOT | 352 // Set verbose level to none if the current function does NOT |
318 // match the -verbose-focus command-line option. | 353 // match the -verbose-focus command-line option. |
319 if (!matchSymbolName(Func->getFunctionName(), | 354 if (!matchSymbolName(Func->getFunctionName(), |
320 getFlags().getVerboseFocusOn())) | 355 getFlags().getVerboseFocusOn())) |
321 Func->setVerbose(IceV_None); | 356 Func->setVerbose(IceV_None); |
322 // Disable translation if -notranslate is specified, or if the | 357 // 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) { | 895 const IceString &NewName) { |
861 auto Timers = &ICE_TLS_GET_FIELD(TLS)->Timers; | 896 auto Timers = &ICE_TLS_GET_FIELD(TLS)->Timers; |
862 assert(StackID < Timers->size()); | 897 assert(StackID < Timers->size()); |
863 Timers->at(StackID).setName(NewName); | 898 Timers->at(StackID).setName(NewName); |
864 } | 899 } |
865 | 900 |
866 // Note: optQueueBlockingPush and optQueueBlockingPop use unique_ptr at the | 901 // Note: optQueueBlockingPush and optQueueBlockingPop use unique_ptr at the |
867 // interface to take and transfer ownership, but they internally store the raw | 902 // 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 | 903 // Cfg pointer in the work queue. This allows e.g. future queue optimizations |
869 // such as the use of atomics to modify queue elements. | 904 // such as the use of atomics to modify queue elements. |
870 void GlobalContext::optQueueBlockingPush(std::unique_ptr<Cfg> Func) { | 905 void GlobalContext::optQueueBlockingPush(std::unique_ptr<OptWorkItem> Item) { |
871 assert(Func); | 906 assert(Item); |
872 { | 907 { |
873 TimerMarker _(TimerStack::TT_qTransPush, this); | 908 TimerMarker _(TimerStack::TT_qTransPush, this); |
874 OptQ.blockingPush(std::move(Func)); | 909 OptQ.blockingPush(std::move(Item)); |
875 } | 910 } |
876 if (getFlags().isSequential()) | 911 if (getFlags().isSequential()) |
877 translateFunctions(); | 912 translateFunctions(); |
878 } | 913 } |
879 | 914 |
880 std::unique_ptr<Cfg> GlobalContext::optQueueBlockingPop() { | 915 std::unique_ptr<OptWorkItem> GlobalContext::optQueueBlockingPop() { |
881 TimerMarker _(TimerStack::TT_qTransPop, this); | 916 TimerMarker _(TimerStack::TT_qTransPop, this); |
882 return std::unique_ptr<Cfg>(OptQ.blockingPop()); | 917 return std::unique_ptr<OptWorkItem>(OptQ.blockingPop()); |
883 } | 918 } |
884 | 919 |
885 void GlobalContext::emitQueueBlockingPush( | 920 void GlobalContext::emitQueueBlockingPush( |
886 std::unique_ptr<EmitterWorkItem> Item) { | 921 std::unique_ptr<EmitterWorkItem> Item) { |
887 assert(Item); | 922 assert(Item); |
888 { | 923 { |
889 TimerMarker _(TimerStack::TT_qEmitPush, this); | 924 TimerMarker _(TimerStack::TT_qEmitPush, this); |
890 EmitQ.blockingPush(std::move(Item)); | 925 EmitQ.blockingPush(std::move(Item)); |
891 } | 926 } |
892 if (getFlags().isSequential()) | 927 if (getFlags().isSequential()) |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
947 Ctx = Func->getContext(); | 982 Ctx = Func->getContext(); |
948 Active = | 983 Active = |
949 Func->getFocusedTiming() || Ctx->getFlags().getSubzeroTimingEnabled(); | 984 Func->getFocusedTiming() || Ctx->getFlags().getSubzeroTimingEnabled(); |
950 if (Active) | 985 if (Active) |
951 Ctx->pushTimer(ID, StackID); | 986 Ctx->pushTimer(ID, StackID); |
952 } | 987 } |
953 | 988 |
954 ICE_TLS_DEFINE_FIELD(GlobalContext::ThreadContext *, GlobalContext, TLS); | 989 ICE_TLS_DEFINE_FIELD(GlobalContext::ThreadContext *, GlobalContext, TLS); |
955 | 990 |
956 } // end of namespace Ice | 991 } // end of namespace Ice |
OLD | NEW |