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 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
206 TypePool<IceType_i8, int8_t, ConstantInteger32> Integers8; | 206 TypePool<IceType_i8, int8_t, ConstantInteger32> Integers8; |
207 TypePool<IceType_i16, int16_t, ConstantInteger32> Integers16; | 207 TypePool<IceType_i16, int16_t, ConstantInteger32> Integers16; |
208 TypePool<IceType_i32, int32_t, ConstantInteger32> Integers32; | 208 TypePool<IceType_i32, int32_t, ConstantInteger32> Integers32; |
209 TypePool<IceType_i64, int64_t, ConstantInteger64> Integers64; | 209 TypePool<IceType_i64, int64_t, ConstantInteger64> Integers64; |
210 TypePool<IceType_i32, RelocatableTuple, ConstantRelocatable> Relocatables; | 210 TypePool<IceType_i32, RelocatableTuple, ConstantRelocatable> Relocatables; |
211 TypePool<IceType_i32, RelocatableTuple, ConstantRelocatable> | 211 TypePool<IceType_i32, RelocatableTuple, ConstantRelocatable> |
212 ExternRelocatables; | 212 ExternRelocatables; |
213 UndefPool Undefs; | 213 UndefPool Undefs; |
214 }; | 214 }; |
215 | 215 |
| 216 void GlobalContext::waitForWorkerThreads() { |
| 217 if (WaitForWorkerThreadsCalled.exchange(true)) |
| 218 return; |
| 219 optQueueNotifyEnd(); |
| 220 for (std::thread &Worker : TranslationThreads) { |
| 221 Worker.join(); |
| 222 } |
| 223 TranslationThreads.clear(); |
| 224 |
| 225 // Only notify the emit queue to end after all the translation threads have |
| 226 // ended. |
| 227 emitQueueNotifyEnd(); |
| 228 for (std::thread &Worker : EmitterThreads) { |
| 229 Worker.join(); |
| 230 } |
| 231 EmitterThreads.clear(); |
| 232 |
| 233 if (BuildDefs::timers()) { |
| 234 auto Timers = getTimers(); |
| 235 for (ThreadContext *TLS : AllThreadContexts) |
| 236 Timers->mergeFrom(TLS->Timers); |
| 237 } |
| 238 if (BuildDefs::dump()) { |
| 239 // Do a separate loop over AllThreadContexts to avoid holding two locks at |
| 240 // once. |
| 241 auto Stats = getStatsCumulative(); |
| 242 for (ThreadContext *TLS : AllThreadContexts) |
| 243 Stats->add(TLS->StatsCumulative); |
| 244 } |
| 245 } |
| 246 |
216 void GlobalContext::CodeStats::dump(const std::string &Name, | 247 void GlobalContext::CodeStats::dump(const std::string &Name, |
217 GlobalContext *Ctx) { | 248 GlobalContext *Ctx) { |
218 if (!BuildDefs::dump()) | 249 if (!BuildDefs::dump()) |
219 return; | 250 return; |
220 OstreamLocker _(Ctx); | 251 OstreamLocker _(Ctx); |
221 Ostream &Str = Ctx->getStrDump(); | 252 Ostream &Str = Ctx->getStrDump(); |
222 #define X(str, tag) \ | 253 #define X(str, tag) \ |
223 Str << "|" << Name << "|" str "|" << Stats[CS_##tag] << "\n"; | 254 Str << "|" << Name << "|" str "|" << Stats[CS_##tag] << "\n"; |
224 CODESTATS_TABLE | 255 CODESTATS_TABLE |
225 #undef X | 256 #undef X |
(...skipping 19 matching lines...) Expand all Loading... |
245 Str << "|ExtRel=" << Pool->ExternRelocatables.size(); | 276 Str << "|ExtRel=" << Pool->ExternRelocatables.size(); |
246 } | 277 } |
247 Str << "\n"; | 278 Str << "\n"; |
248 } | 279 } |
249 | 280 |
250 GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError, | 281 GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError, |
251 ELFStreamer *ELFStr) | 282 ELFStreamer *ELFStr) |
252 : Strings(new StringPool()), ConstPool(new ConstantPool()), ErrorStatus(), | 283 : Strings(new StringPool()), ConstPool(new ConstantPool()), ErrorStatus(), |
253 StrDump(OsDump), StrEmit(OsEmit), StrError(OsError), IntrinsicsInfo(this), | 284 StrDump(OsDump), StrEmit(OsEmit), StrError(OsError), IntrinsicsInfo(this), |
254 ObjectWriter(), OptQ(/*Sequential=*/Flags.isSequential(), | 285 ObjectWriter(), OptQ(/*Sequential=*/Flags.isSequential(), |
255 /*MaxSize=*/Flags.getNumTranslationThreads()), | 286 /*MaxSize=*/ |
| 287 (Flags.getParseParallel() && Flags.getBuildOnRead()) |
| 288 ? MaxOptQSize |
| 289 : Flags.getNumTranslationThreads()), |
256 // EmitQ is allowed unlimited size. | 290 // EmitQ is allowed unlimited size. |
257 EmitQ(/*Sequential=*/Flags.isSequential()), | 291 EmitQ(/*Sequential=*/Flags.isSequential()), |
258 DataLowering(TargetDataLowering::createLowering(this)) { | 292 DataLowering(TargetDataLowering::createLowering(this)) { |
259 assert(OsDump && "OsDump is not defined for GlobalContext"); | 293 assert(OsDump && "OsDump is not defined for GlobalContext"); |
260 assert(OsEmit && "OsEmit is not defined for GlobalContext"); | 294 assert(OsEmit && "OsEmit is not defined for GlobalContext"); |
261 assert(OsError && "OsError is not defined for GlobalContext"); | 295 assert(OsError && "OsError is not defined for GlobalContext"); |
262 // Make sure thread_local fields are properly initialized before any | 296 // Make sure thread_local fields are properly initialized before any |
263 // accesses are made. Do this here instead of at the start of | 297 // accesses are made. Do this here instead of at the start of |
264 // main() so that all clients (e.g. unit tests) can benefit for | 298 // main() so that all clients (e.g. unit tests) can benefit for |
265 // free. | 299 // free. |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
298 RuntimeHelperFunc[static_cast<size_t>(RuntimeHelper::H_##Tag)] = \ | 332 RuntimeHelperFunc[static_cast<size_t>(RuntimeHelper::H_##Tag)] = \ |
299 getConstantExternSym(getGlobalString(Name)); | 333 getConstantExternSym(getGlobalString(Name)); |
300 RUNTIME_HELPER_FUNCTIONS_TABLE | 334 RUNTIME_HELPER_FUNCTIONS_TABLE |
301 #undef X | 335 #undef X |
302 | 336 |
303 TargetLowering::staticInit(this); | 337 TargetLowering::staticInit(this); |
304 } | 338 } |
305 | 339 |
306 void GlobalContext::translateFunctions() { | 340 void GlobalContext::translateFunctions() { |
307 TimerMarker Timer(TimerStack::TT_translateFunctions, this); | 341 TimerMarker Timer(TimerStack::TT_translateFunctions, this); |
308 while (std::unique_ptr<Cfg> Func = optQueueBlockingPop()) { | 342 while (std::unique_ptr<OptWorkItem> OptItem = optQueueBlockingPop()) { |
| 343 auto Func = OptItem->getParsedCfg(); |
309 // Install Func in TLS for Cfg-specific container allocators. | 344 // Install Func in TLS for Cfg-specific container allocators. |
310 CfgLocalAllocatorScope _(Func.get()); | 345 CfgLocalAllocatorScope _(Func.get()); |
311 // Reset per-function stats being accumulated in TLS. | 346 // Reset per-function stats being accumulated in TLS. |
312 resetStats(); | 347 resetStats(); |
313 // Set verbose level to none if the current function does NOT | 348 // Set verbose level to none if the current function does NOT |
314 // match the -verbose-focus command-line option. | 349 // match the -verbose-focus command-line option. |
315 if (!matchSymbolName(Func->getFunctionName(), | 350 if (!matchSymbolName(Func->getFunctionName(), |
316 getFlags().getVerboseFocusOn())) | 351 getFlags().getVerboseFocusOn())) |
317 Func->setVerbose(IceV_None); | 352 Func->setVerbose(IceV_None); |
318 // Disable translation if -notranslate is specified, or if the | 353 // Disable translation if -notranslate is specified, or if the |
(...skipping 552 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
871 const std::string &NewName) { | 906 const std::string &NewName) { |
872 auto Timers = &ICE_TLS_GET_FIELD(TLS)->Timers; | 907 auto Timers = &ICE_TLS_GET_FIELD(TLS)->Timers; |
873 assert(StackID < Timers->size()); | 908 assert(StackID < Timers->size()); |
874 Timers->at(StackID).setName(NewName); | 909 Timers->at(StackID).setName(NewName); |
875 } | 910 } |
876 | 911 |
877 // Note: optQueueBlockingPush and optQueueBlockingPop use unique_ptr at the | 912 // Note: optQueueBlockingPush and optQueueBlockingPop use unique_ptr at the |
878 // interface to take and transfer ownership, but they internally store the raw | 913 // interface to take and transfer ownership, but they internally store the raw |
879 // Cfg pointer in the work queue. This allows e.g. future queue optimizations | 914 // Cfg pointer in the work queue. This allows e.g. future queue optimizations |
880 // such as the use of atomics to modify queue elements. | 915 // such as the use of atomics to modify queue elements. |
881 void GlobalContext::optQueueBlockingPush(std::unique_ptr<Cfg> Func) { | 916 void GlobalContext::optQueueBlockingPush(std::unique_ptr<OptWorkItem> Item) { |
882 assert(Func); | 917 assert(Item); |
883 { | 918 { |
884 TimerMarker _(TimerStack::TT_qTransPush, this); | 919 TimerMarker _(TimerStack::TT_qTransPush, this); |
885 OptQ.blockingPush(std::move(Func)); | 920 OptQ.blockingPush(std::move(Item)); |
886 } | 921 } |
887 if (getFlags().isSequential()) | 922 if (getFlags().isSequential()) |
888 translateFunctions(); | 923 translateFunctions(); |
889 } | 924 } |
890 | 925 |
891 std::unique_ptr<Cfg> GlobalContext::optQueueBlockingPop() { | 926 std::unique_ptr<OptWorkItem> GlobalContext::optQueueBlockingPop() { |
892 TimerMarker _(TimerStack::TT_qTransPop, this); | 927 TimerMarker _(TimerStack::TT_qTransPop, this); |
893 return std::unique_ptr<Cfg>(OptQ.blockingPop()); | 928 return std::unique_ptr<OptWorkItem>(OptQ.blockingPop()); |
894 } | 929 } |
895 | 930 |
896 void GlobalContext::emitQueueBlockingPush( | 931 void GlobalContext::emitQueueBlockingPush( |
897 std::unique_ptr<EmitterWorkItem> Item) { | 932 std::unique_ptr<EmitterWorkItem> Item) { |
898 assert(Item); | 933 assert(Item); |
899 { | 934 { |
900 TimerMarker _(TimerStack::TT_qEmitPush, this); | 935 TimerMarker _(TimerStack::TT_qEmitPush, this); |
901 EmitQ.blockingPush(std::move(Item)); | 936 EmitQ.blockingPush(std::move(Item)); |
902 } | 937 } |
903 if (getFlags().isSequential()) | 938 if (getFlags().isSequential()) |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
963 Ctx = Func->getContext(); | 998 Ctx = Func->getContext(); |
964 Active = | 999 Active = |
965 Func->getFocusedTiming() || Ctx->getFlags().getSubzeroTimingEnabled(); | 1000 Func->getFocusedTiming() || Ctx->getFlags().getSubzeroTimingEnabled(); |
966 if (Active) | 1001 if (Active) |
967 Ctx->pushTimer(ID, StackID); | 1002 Ctx->pushTimer(ID, StackID); |
968 } | 1003 } |
969 | 1004 |
970 ICE_TLS_DEFINE_FIELD(GlobalContext::ThreadContext *, GlobalContext, TLS); | 1005 ICE_TLS_DEFINE_FIELD(GlobalContext::ThreadContext *, GlobalContext, TLS); |
971 | 1006 |
972 } // end of namespace Ice | 1007 } // end of namespace Ice |
OLD | NEW |