OLD | NEW |
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 /// \file | 10 /// \file |
(...skipping 279 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
290 T *Ret = getAllocator()->Allocate<T>(); | 290 T *Ret = getAllocator()->Allocate<T>(); |
291 getDestructors()->emplace_back([Ret]() { Ret->~T(); }); | 291 getDestructors()->emplace_back([Ret]() { Ret->~T(); }); |
292 return Ret; | 292 return Ret; |
293 } | 293 } |
294 | 294 |
295 const Intrinsics &getIntrinsicsInfo() const { return IntrinsicsInfo; } | 295 const Intrinsics &getIntrinsicsInfo() const { return IntrinsicsInfo; } |
296 | 296 |
297 ELFObjectWriter *getObjectWriter() const { return ObjectWriter.get(); } | 297 ELFObjectWriter *getObjectWriter() const { return ObjectWriter.get(); } |
298 | 298 |
299 /// Reset stats at the beginning of a function. | 299 /// Reset stats at the beginning of a function. |
300 void resetStats() { | 300 void resetStats(); |
301 if (BuildDefs::dump()) | |
302 ICE_TLS_GET_FIELD(TLS)->StatsFunction.reset(); | |
303 } | |
304 void dumpStats(const Cfg *Func = nullptr); | 301 void dumpStats(const Cfg *Func = nullptr); |
305 void statsUpdateEmitted(uint32_t InstCount) { | 302 void statsUpdateEmitted(uint32_t InstCount); |
306 if (!getFlags().getDumpStats()) | 303 void statsUpdateRegistersSaved(uint32_t Num); |
307 return; | 304 void statsUpdateFrameBytes(uint32_t Bytes); |
308 ThreadContext *Tls = ICE_TLS_GET_FIELD(TLS); | 305 void statsUpdateSpills(); |
309 Tls->StatsFunction.update(CodeStats::CS_InstCount, InstCount); | 306 void statsUpdateFills(); |
310 Tls->StatsCumulative.update(CodeStats::CS_InstCount, InstCount); | |
311 } | |
312 void statsUpdateRegistersSaved(uint32_t Num) { | |
313 if (!getFlags().getDumpStats()) | |
314 return; | |
315 ThreadContext *Tls = ICE_TLS_GET_FIELD(TLS); | |
316 Tls->StatsFunction.update(CodeStats::CS_RegsSaved, Num); | |
317 Tls->StatsCumulative.update(CodeStats::CS_RegsSaved, Num); | |
318 } | |
319 void statsUpdateFrameBytes(uint32_t Bytes) { | |
320 if (!getFlags().getDumpStats()) | |
321 return; | |
322 ThreadContext *Tls = ICE_TLS_GET_FIELD(TLS); | |
323 Tls->StatsFunction.update(CodeStats::CS_FrameByte, Bytes); | |
324 Tls->StatsCumulative.update(CodeStats::CS_FrameByte, Bytes); | |
325 } | |
326 void statsUpdateSpills() { | |
327 if (!getFlags().getDumpStats()) | |
328 return; | |
329 ThreadContext *Tls = ICE_TLS_GET_FIELD(TLS); | |
330 Tls->StatsFunction.update(CodeStats::CS_NumSpills); | |
331 Tls->StatsCumulative.update(CodeStats::CS_NumSpills); | |
332 } | |
333 void statsUpdateFills() { | |
334 if (!getFlags().getDumpStats()) | |
335 return; | |
336 ThreadContext *Tls = ICE_TLS_GET_FIELD(TLS); | |
337 Tls->StatsFunction.update(CodeStats::CS_NumFills); | |
338 Tls->StatsCumulative.update(CodeStats::CS_NumFills); | |
339 } | |
340 | 307 |
341 /// Number of Randomized or Pooled Immediates | 308 /// Number of Randomized or Pooled Immediates |
342 void statsUpdateRPImms() { | 309 void statsUpdateRPImms(); |
343 if (!getFlags().getDumpStats()) | |
344 return; | |
345 ThreadContext *Tls = ICE_TLS_GET_FIELD(TLS); | |
346 Tls->StatsFunction.update(CodeStats::CS_NumRPImms); | |
347 Tls->StatsCumulative.update(CodeStats::CS_NumRPImms); | |
348 } | |
349 | 310 |
350 /// These are predefined TimerStackIdT values. | 311 /// These are predefined TimerStackIdT values. |
351 enum TimerStackKind { TSK_Default = 0, TSK_Funcs, TSK_Num }; | 312 enum TimerStackKind { TSK_Default = 0, TSK_Funcs, TSK_Num }; |
352 | 313 |
353 /// newTimerStackID() creates a new TimerStack in the global space. It does | 314 /// newTimerStackID() creates a new TimerStack in the global space. It does |
354 /// not affect any TimerStack objects in TLS. | 315 /// not affect any TimerStack objects in TLS. |
355 TimerStackIdT newTimerStackID(const std::string &Name); | 316 TimerStackIdT newTimerStackID(const std::string &Name); |
356 /// dumpTimers() dumps the global timer data. This assumes all the | 317 /// dumpTimers() dumps the global timer data. This assumes all the |
357 /// thread-local copies of timer data have been merged into the global timer | 318 /// thread-local copies of timer data have been merged into the global timer |
358 /// data. | 319 /// data. |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
396 void lowerJumpTables(); | 357 void lowerJumpTables(); |
397 | 358 |
398 /// Emit target specific read-only data sections if any. E.g., for MIPS this | 359 /// Emit target specific read-only data sections if any. E.g., for MIPS this |
399 /// generates a .MIPS.abiflags section. | 360 /// generates a .MIPS.abiflags section. |
400 void emitTargetRODataSections(); | 361 void emitTargetRODataSections(); |
401 | 362 |
402 void emitQueueBlockingPush(std::unique_ptr<EmitterWorkItem> Item); | 363 void emitQueueBlockingPush(std::unique_ptr<EmitterWorkItem> Item); |
403 std::unique_ptr<EmitterWorkItem> emitQueueBlockingPop(); | 364 std::unique_ptr<EmitterWorkItem> emitQueueBlockingPop(); |
404 void emitQueueNotifyEnd() { EmitQ.notifyEnd(); } | 365 void emitQueueNotifyEnd() { EmitQ.notifyEnd(); } |
405 | 366 |
406 void initParserThread() { | 367 void initParserThread(); |
407 ThreadContext *Tls = new ThreadContext(); | 368 void startWorkerThreads(); |
408 auto Timers = getTimers(); | |
409 Timers->initInto(Tls->Timers); | |
410 AllThreadContexts.push_back(Tls); | |
411 ICE_TLS_SET_FIELD(TLS, Tls); | |
412 } | |
413 | |
414 void startWorkerThreads() { | |
415 size_t NumWorkers = getFlags().getNumTranslationThreads(); | |
416 auto Timers = getTimers(); | |
417 for (size_t i = 0; i < NumWorkers; ++i) { | |
418 ThreadContext *WorkerTLS = new ThreadContext(); | |
419 Timers->initInto(WorkerTLS->Timers); | |
420 AllThreadContexts.push_back(WorkerTLS); | |
421 TranslationThreads.push_back(std::thread( | |
422 &GlobalContext::translateFunctionsWrapper, this, WorkerTLS)); | |
423 } | |
424 if (NumWorkers) { | |
425 ThreadContext *WorkerTLS = new ThreadContext(); | |
426 Timers->initInto(WorkerTLS->Timers); | |
427 AllThreadContexts.push_back(WorkerTLS); | |
428 EmitterThreads.push_back( | |
429 std::thread(&GlobalContext::emitterWrapper, this, WorkerTLS)); | |
430 } | |
431 } | |
432 | 369 |
433 void waitForWorkerThreads(); | 370 void waitForWorkerThreads(); |
434 | 371 |
435 /// sets the instrumentation object to use. | 372 /// sets the instrumentation object to use. |
436 void setInstrumentation(std::unique_ptr<Instrumentation> Instr) { | 373 void setInstrumentation(std::unique_ptr<Instrumentation> Instr) { |
437 if (!BuildDefs::minimal()) | 374 if (!BuildDefs::minimal()) |
438 Instrumentor = std::move(Instr); | 375 Instrumentor = std::move(Instr); |
439 } | 376 } |
440 | 377 |
441 void instrumentFunc(Cfg *Func) { | 378 void instrumentFunc(Cfg *Func) { |
442 if (!BuildDefs::minimal() && Instrumentor) | 379 if (!BuildDefs::minimal() && Instrumentor) |
443 Instrumentor->instrumentFunc(Func); | 380 Instrumentor->instrumentFunc(Func); |
444 } | 381 } |
445 | 382 |
446 /// Translation thread startup routine. | 383 /// Translation thread startup routine. |
447 void translateFunctionsWrapper(ThreadContext *MyTLS) { | 384 void translateFunctionsWrapper(ThreadContext *MyTLS); |
448 ICE_TLS_SET_FIELD(TLS, MyTLS); | |
449 translateFunctions(); | |
450 } | |
451 /// Translate functions from the Cfg queue until the queue is empty. | 385 /// Translate functions from the Cfg queue until the queue is empty. |
452 void translateFunctions(); | 386 void translateFunctions(); |
453 | 387 |
454 /// Emitter thread startup routine. | 388 /// Emitter thread startup routine. |
455 void emitterWrapper(ThreadContext *MyTLS) { | 389 void emitterWrapper(ThreadContext *MyTLS); |
456 ICE_TLS_SET_FIELD(TLS, MyTLS); | |
457 emitItems(); | |
458 } | |
459 /// Emit functions and global initializers from the emitter queue until the | 390 /// Emit functions and global initializers from the emitter queue until the |
460 /// queue is empty. | 391 /// queue is empty. |
461 void emitItems(); | 392 void emitItems(); |
462 | 393 |
463 /// Uses DataLowering to lower Globals. Side effects: | 394 /// Uses DataLowering to lower Globals. Side effects: |
464 /// - discards the initializer list for the global variable in Globals. | 395 /// - discards the initializer list for the global variable in Globals. |
465 /// - clears the Globals array. | 396 /// - clears the Globals array. |
466 void lowerGlobals(const std::string &SectionSuffix); | 397 void lowerGlobals(const std::string &SectionSuffix); |
467 | 398 |
468 /// Lowers the profile information. | 399 /// Lowers the profile information. |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
636 void saveBlockInfoPtrs(); | 567 void saveBlockInfoPtrs(); |
637 | 568 |
638 llvm::SmallVector<ThreadContext *, 128> AllThreadContexts; | 569 llvm::SmallVector<ThreadContext *, 128> AllThreadContexts; |
639 llvm::SmallVector<std::thread, 128> TranslationThreads; | 570 llvm::SmallVector<std::thread, 128> TranslationThreads; |
640 llvm::SmallVector<std::thread, 128> EmitterThreads; | 571 llvm::SmallVector<std::thread, 128> EmitterThreads; |
641 // Each thread has its own TLS pointer which is also held in | 572 // Each thread has its own TLS pointer which is also held in |
642 // AllThreadContexts. | 573 // AllThreadContexts. |
643 ICE_TLS_DECLARE_FIELD(ThreadContext *, TLS); | 574 ICE_TLS_DECLARE_FIELD(ThreadContext *, TLS); |
644 | 575 |
645 public: | 576 public: |
646 static void TlsInit() { ICE_TLS_INIT_FIELD(TLS); } | 577 static void TlsInit(); |
647 }; | 578 }; |
648 | 579 |
649 /// Helper class to push and pop a timer marker. The constructor pushes a | 580 /// Helper class to push and pop a timer marker. The constructor pushes a |
650 /// marker, and the destructor pops it. This is for convenient timing of regions | 581 /// marker, and the destructor pops it. This is for convenient timing of regions |
651 /// of code. | 582 /// of code. |
652 class TimerMarker { | 583 class TimerMarker { |
653 TimerMarker() = delete; | 584 TimerMarker() = delete; |
654 TimerMarker(const TimerMarker &) = delete; | 585 TimerMarker(const TimerMarker &) = delete; |
655 TimerMarker &operator=(const TimerMarker &) = delete; | 586 TimerMarker &operator=(const TimerMarker &) = delete; |
656 | 587 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
702 explicit OstreamLocker(GlobalContext *Ctx) : Ctx(Ctx) { Ctx->lockStr(); } | 633 explicit OstreamLocker(GlobalContext *Ctx) : Ctx(Ctx) { Ctx->lockStr(); } |
703 ~OstreamLocker() { Ctx->unlockStr(); } | 634 ~OstreamLocker() { Ctx->unlockStr(); } |
704 | 635 |
705 private: | 636 private: |
706 GlobalContext *const Ctx; | 637 GlobalContext *const Ctx; |
707 }; | 638 }; |
708 | 639 |
709 } // end of namespace Ice | 640 } // end of namespace Ice |
710 | 641 |
711 #endif // SUBZERO_SRC_ICEGLOBALCONTEXT_H | 642 #endif // SUBZERO_SRC_ICEGLOBALCONTEXT_H |
OLD | NEW |