| 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 |
| 11 /// \brief Declares aspects of the compilation that persist across multiple | 11 /// \brief Declares aspects of the compilation that persist across multiple |
| 12 /// functions. | 12 /// functions. |
| 13 /// | 13 /// |
| 14 //===----------------------------------------------------------------------===// | 14 //===----------------------------------------------------------------------===// |
| 15 | 15 |
| 16 #ifndef SUBZERO_SRC_ICEGLOBALCONTEXT_H | 16 #ifndef SUBZERO_SRC_ICEGLOBALCONTEXT_H |
| 17 #define SUBZERO_SRC_ICEGLOBALCONTEXT_H | 17 #define SUBZERO_SRC_ICEGLOBALCONTEXT_H |
| 18 | 18 |
| 19 #include "IceDefs.h" | 19 #include "IceDefs.h" |
| 20 #include "IceClFlags.h" | 20 #include "IceClFlags.h" |
| 21 #include "IceIntrinsics.h" | 21 #include "IceIntrinsics.h" |
| 22 #include "IceRNG.h" | 22 #include "IceRNG.h" |
| 23 #include "IceStringPool.h" |
| 23 #include "IceSwitchLowering.h" | 24 #include "IceSwitchLowering.h" |
| 24 #include "IceTargetLowering.def" | 25 #include "IceTargetLowering.def" |
| 25 #include "IceThreading.h" | 26 #include "IceThreading.h" |
| 26 #include "IceTimerTree.h" | 27 #include "IceTimerTree.h" |
| 27 #include "IceTypes.h" | 28 #include "IceTypes.h" |
| 28 #include "IceUtils.h" | 29 #include "IceUtils.h" |
| 29 | 30 |
| 30 #include <array> | 31 #include <array> |
| 31 #include <cassert> | 32 #include <cassert> |
| 32 #include <functional> | 33 #include <functional> |
| (...skipping 13 matching lines...) Expand all Loading... |
| 46 | 47 |
| 47 // Runtime helper function IDs | 48 // Runtime helper function IDs |
| 48 | 49 |
| 49 enum class RuntimeHelper { | 50 enum class RuntimeHelper { |
| 50 #define X(Tag, Name) H_##Tag, | 51 #define X(Tag, Name) H_##Tag, |
| 51 RUNTIME_HELPER_FUNCTIONS_TABLE | 52 RUNTIME_HELPER_FUNCTIONS_TABLE |
| 52 #undef X | 53 #undef X |
| 53 H_Num | 54 H_Num |
| 54 }; | 55 }; |
| 55 | 56 |
| 56 /// LockedPtr is a way to provide automatically locked access to some object. | |
| 57 template <typename T> class LockedPtr { | |
| 58 LockedPtr() = delete; | |
| 59 LockedPtr(const LockedPtr &) = delete; | |
| 60 LockedPtr &operator=(const LockedPtr &) = delete; | |
| 61 | |
| 62 public: | |
| 63 LockedPtr(T *Value, GlobalLockType *Lock) : Value(Value), Lock(Lock) { | |
| 64 Lock->lock(); | |
| 65 } | |
| 66 LockedPtr(LockedPtr &&Other) : Value(Other.Value), Lock(Other.Lock) { | |
| 67 Other.Value = nullptr; | |
| 68 Other.Lock = nullptr; | |
| 69 } | |
| 70 ~LockedPtr() { Lock->unlock(); } | |
| 71 T *operator->() const { return Value; } | |
| 72 T &operator*() const { return *Value; } | |
| 73 T *get() { return Value; } | |
| 74 | |
| 75 private: | |
| 76 T *Value; | |
| 77 GlobalLockType *Lock; | |
| 78 }; | |
| 79 | |
| 80 class GlobalContext { | 57 class GlobalContext { |
| 81 GlobalContext() = delete; | 58 GlobalContext() = delete; |
| 82 GlobalContext(const GlobalContext &) = delete; | 59 GlobalContext(const GlobalContext &) = delete; |
| 83 GlobalContext &operator=(const GlobalContext &) = delete; | 60 GlobalContext &operator=(const GlobalContext &) = delete; |
| 84 | 61 |
| 85 /// CodeStats collects rudimentary statistics during translation. | 62 /// CodeStats collects rudimentary statistics during translation. |
| 86 class CodeStats { | 63 class CodeStats { |
| 87 CodeStats(const CodeStats &) = delete; | 64 CodeStats(const CodeStats &) = delete; |
| 88 CodeStats &operator=(const CodeStats &) = default; | 65 CodeStats &operator=(const CodeStats &) = default; |
| 89 #define CODESTATS_TABLE \ | 66 #define CODESTATS_TABLE \ |
| (...skipping 16 matching lines...) Expand all Loading... |
| 106 CodeStats() { reset(); } | 83 CodeStats() { reset(); } |
| 107 void reset() { Stats.fill(0); } | 84 void reset() { Stats.fill(0); } |
| 108 void update(CSTag Tag, uint32_t Count = 1) { | 85 void update(CSTag Tag, uint32_t Count = 1) { |
| 109 assert(Tag < Stats.size()); | 86 assert(Tag < Stats.size()); |
| 110 Stats[Tag] += Count; | 87 Stats[Tag] += Count; |
| 111 } | 88 } |
| 112 void add(const CodeStats &Other) { | 89 void add(const CodeStats &Other) { |
| 113 for (uint32_t i = 0; i < Stats.size(); ++i) | 90 for (uint32_t i = 0; i < Stats.size(); ++i) |
| 114 Stats[i] += Other.Stats[i]; | 91 Stats[i] += Other.Stats[i]; |
| 115 } | 92 } |
| 116 void dump(const IceString &Name, GlobalContext *Ctx); | 93 void dump(const std::string &Name, GlobalContext *Ctx); |
| 117 | 94 |
| 118 private: | 95 private: |
| 119 std::array<uint32_t, CS_NUM> Stats; | 96 std::array<uint32_t, CS_NUM> Stats; |
| 120 }; | 97 }; |
| 121 | 98 |
| 122 /// TimerList is a vector of TimerStack objects, with extra methods | 99 /// TimerList is a vector of TimerStack objects, with extra methods |
| 123 /// to initialize and merge these vectors. | 100 /// to initialize and merge these vectors. |
| 124 class TimerList : public std::vector<TimerStack> { | 101 class TimerList : public std::vector<TimerStack> { |
| 125 TimerList(const TimerList &) = delete; | 102 TimerList(const TimerList &) = delete; |
| 126 TimerList &operator=(const TimerList &) = delete; | 103 TimerList &operator=(const TimerList &) = delete; |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 165 TimerList Timers; | 142 TimerList Timers; |
| 166 }; | 143 }; |
| 167 | 144 |
| 168 public: | 145 public: |
| 169 /// The dump stream is a log stream while emit is the stream code | 146 /// The dump stream is a log stream while emit is the stream code |
| 170 /// is emitted to. The error stream is strictly for logging errors. | 147 /// is emitted to. The error stream is strictly for logging errors. |
| 171 GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError, | 148 GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError, |
| 172 ELFStreamer *ELFStreamer); | 149 ELFStreamer *ELFStreamer); |
| 173 ~GlobalContext(); | 150 ~GlobalContext(); |
| 174 | 151 |
| 152 void dumpStrings(); |
| 175 /// | 153 /// |
| 176 /// The dump, error, and emit streams need to be used by only one | 154 /// The dump, error, and emit streams need to be used by only one |
| 177 /// thread at a time. This is done by exclusively reserving the | 155 /// thread at a time. This is done by exclusively reserving the |
| 178 /// streams via lockStr() and unlockStr(). The OstreamLocker class | 156 /// streams via lockStr() and unlockStr(). The OstreamLocker class |
| 179 /// can be used to conveniently manage this. | 157 /// can be used to conveniently manage this. |
| 180 /// | 158 /// |
| 181 /// The model is that a thread grabs the stream lock, then does an | 159 /// The model is that a thread grabs the stream lock, then does an |
| 182 /// arbitrary amount of work during which far-away callees may grab | 160 /// arbitrary amount of work during which far-away callees may grab |
| 183 /// the stream and do something with it, and finally the thread | 161 /// the stream and do something with it, and finally the thread |
| 184 /// releases the stream lock. This allows large chunks of output to | 162 /// releases the stream lock. This allows large chunks of output to |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 240 switch (ConstantInt64) { | 218 switch (ConstantInt64) { |
| 241 case 0: | 219 case 0: |
| 242 return getConstantZero(IceType_i64); | 220 return getConstantZero(IceType_i64); |
| 243 default: | 221 default: |
| 244 return getConstantInt64Internal(ConstantInt64); | 222 return getConstantInt64Internal(ConstantInt64); |
| 245 } | 223 } |
| 246 } | 224 } |
| 247 Constant *getConstantFloat(float Value); | 225 Constant *getConstantFloat(float Value); |
| 248 Constant *getConstantDouble(double Value); | 226 Constant *getConstantDouble(double Value); |
| 249 /// Returns a symbolic constant. | 227 /// Returns a symbolic constant. |
| 250 Constant *getConstantSym(const RelocOffsetT Offset, | 228 Constant *getConstantSymWithEmitString(const RelocOffsetT Offset, |
| 251 const RelocOffsetArray &OffsetExpr, | 229 const RelocOffsetArray &OffsetExpr, |
| 252 const IceString &Name, const IceString &EmitString); | 230 GlobalString Name, |
| 253 Constant *getConstantSym(RelocOffsetT Offset, const IceString &Name); | 231 const std::string &EmitString); |
| 254 Constant *getConstantExternSym(const IceString &Name); | 232 Constant *getConstantSym(RelocOffsetT Offset, GlobalString Name); |
| 233 Constant *getConstantExternSym(GlobalString Name); |
| 255 /// Returns an undef. | 234 /// Returns an undef. |
| 256 Constant *getConstantUndef(Type Ty); | 235 Constant *getConstantUndef(Type Ty); |
| 257 /// Returns a zero value. | 236 /// Returns a zero value. |
| 258 Constant *getConstantZero(Type Ty); | 237 Constant *getConstantZero(Type Ty); |
| 259 /// getConstantPool() returns a copy of the constant pool for constants of a | 238 /// getConstantPool() returns a copy of the constant pool for constants of a |
| 260 /// given type. | 239 /// given type. |
| 261 ConstantList getConstantPool(Type Ty); | 240 ConstantList getConstantPool(Type Ty); |
| 262 /// Returns a copy of the list of external symbols. | 241 /// Returns a copy of the list of external symbols. |
| 263 ConstantList getConstantExternSyms(); | 242 ConstantList getConstantExternSyms(); |
| 264 /// @} | 243 /// @} |
| 265 Constant *getRuntimeHelperFunc(RuntimeHelper FuncID) const { | 244 Constant *getRuntimeHelperFunc(RuntimeHelper FuncID) const { |
| 266 assert(FuncID < RuntimeHelper::H_Num); | 245 assert(FuncID < RuntimeHelper::H_Num); |
| 267 Constant *Result = RuntimeHelperFunc[static_cast<size_t>(FuncID)]; | 246 Constant *Result = RuntimeHelperFunc[static_cast<size_t>(FuncID)]; |
| 268 assert(Result != nullptr && "No such runtime helper function"); | 247 assert(Result != nullptr && "No such runtime helper function"); |
| 269 return Result; | 248 return Result; |
| 270 } | 249 } |
| 250 GlobalString getGlobalString(const std::string &Name); |
| 271 | 251 |
| 272 /// Return a locked pointer to the registered jump tables. | 252 /// Return a locked pointer to the registered jump tables. |
| 273 JumpTableDataList getJumpTables(); | 253 JumpTableDataList getJumpTables(); |
| 274 /// Create a new jump table entry and return a reference to it. | 254 /// Create a new jump table entry and return a reference to it. |
| 275 JumpTableData &addJumpTable(const IceString &FuncName, SizeT Id, | 255 JumpTableData &addJumpTable(GlobalString FuncName, SizeT Id, |
| 276 const JumpTableData::TargetList &TargetList); | 256 const JumpTableData::TargetList &TargetList); |
| 277 | 257 |
| 278 static const ClFlags &getFlags() { return Flags; } | 258 static const ClFlags &getFlags() { return Flags; } |
| 279 | 259 |
| 280 /// Allocate data of type T using the global allocator. We allow entities | 260 /// Allocate data of type T using the global allocator. We allow entities |
| 281 /// allocated from this global allocator to be either trivially or | 261 /// allocated from this global allocator to be either trivially or |
| 282 /// non-trivially destructible. We optimize the case when T is trivially | 262 /// non-trivially destructible. We optimize the case when T is trivially |
| 283 /// destructible by not registering a destructor. Destructors will be invoked | 263 /// destructible by not registering a destructor. Destructors will be invoked |
| 284 /// during GlobalContext destruction in the reverse object creation order. | 264 /// during GlobalContext destruction in the reverse object creation order. |
| 285 template <typename T> | 265 template <typename T> |
| (...skipping 12 matching lines...) Expand all Loading... |
| 298 | 278 |
| 299 const Intrinsics &getIntrinsicsInfo() const { return IntrinsicsInfo; } | 279 const Intrinsics &getIntrinsicsInfo() const { return IntrinsicsInfo; } |
| 300 | 280 |
| 301 ELFObjectWriter *getObjectWriter() const { return ObjectWriter.get(); } | 281 ELFObjectWriter *getObjectWriter() const { return ObjectWriter.get(); } |
| 302 | 282 |
| 303 /// Reset stats at the beginning of a function. | 283 /// Reset stats at the beginning of a function. |
| 304 void resetStats() { | 284 void resetStats() { |
| 305 if (BuildDefs::dump()) | 285 if (BuildDefs::dump()) |
| 306 ICE_TLS_GET_FIELD(TLS)->StatsFunction.reset(); | 286 ICE_TLS_GET_FIELD(TLS)->StatsFunction.reset(); |
| 307 } | 287 } |
| 308 void dumpStats(const IceString &Name, bool Final = false); | 288 void dumpStats(const std::string &Name, bool Final = false); |
| 309 void statsUpdateEmitted(uint32_t InstCount) { | 289 void statsUpdateEmitted(uint32_t InstCount) { |
| 310 if (!getFlags().getDumpStats()) | 290 if (!getFlags().getDumpStats()) |
| 311 return; | 291 return; |
| 312 ThreadContext *Tls = ICE_TLS_GET_FIELD(TLS); | 292 ThreadContext *Tls = ICE_TLS_GET_FIELD(TLS); |
| 313 Tls->StatsFunction.update(CodeStats::CS_InstCount, InstCount); | 293 Tls->StatsFunction.update(CodeStats::CS_InstCount, InstCount); |
| 314 Tls->StatsCumulative.update(CodeStats::CS_InstCount, InstCount); | 294 Tls->StatsCumulative.update(CodeStats::CS_InstCount, InstCount); |
| 315 } | 295 } |
| 316 void statsUpdateRegistersSaved(uint32_t Num) { | 296 void statsUpdateRegistersSaved(uint32_t Num) { |
| 317 if (!getFlags().getDumpStats()) | 297 if (!getFlags().getDumpStats()) |
| 318 return; | 298 return; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 349 ThreadContext *Tls = ICE_TLS_GET_FIELD(TLS); | 329 ThreadContext *Tls = ICE_TLS_GET_FIELD(TLS); |
| 350 Tls->StatsFunction.update(CodeStats::CS_NumRPImms); | 330 Tls->StatsFunction.update(CodeStats::CS_NumRPImms); |
| 351 Tls->StatsCumulative.update(CodeStats::CS_NumRPImms); | 331 Tls->StatsCumulative.update(CodeStats::CS_NumRPImms); |
| 352 } | 332 } |
| 353 | 333 |
| 354 /// These are predefined TimerStackIdT values. | 334 /// These are predefined TimerStackIdT values. |
| 355 enum TimerStackKind { TSK_Default = 0, TSK_Funcs, TSK_Num }; | 335 enum TimerStackKind { TSK_Default = 0, TSK_Funcs, TSK_Num }; |
| 356 | 336 |
| 357 /// newTimerStackID() creates a new TimerStack in the global space. It does | 337 /// newTimerStackID() creates a new TimerStack in the global space. It does |
| 358 /// not affect any TimerStack objects in TLS. | 338 /// not affect any TimerStack objects in TLS. |
| 359 TimerStackIdT newTimerStackID(const IceString &Name); | 339 TimerStackIdT newTimerStackID(const std::string &Name); |
| 360 /// dumpTimers() dumps the global timer data. As such, one probably wants to | 340 /// dumpTimers() dumps the global timer data. As such, one probably wants to |
| 361 /// call mergeTimerStacks() as a prerequisite. | 341 /// call mergeTimerStacks() as a prerequisite. |
| 362 void dumpTimers(TimerStackIdT StackID = TSK_Default, | 342 void dumpTimers(TimerStackIdT StackID = TSK_Default, |
| 363 bool DumpCumulative = true); | 343 bool DumpCumulative = true); |
| 364 /// The following methods affect only the calling thread's TLS timer data. | 344 /// The following methods affect only the calling thread's TLS timer data. |
| 365 TimerIdT getTimerID(TimerStackIdT StackID, const IceString &Name); | 345 TimerIdT getTimerID(TimerStackIdT StackID, const std::string &Name); |
| 366 void pushTimer(TimerIdT ID, TimerStackIdT StackID); | 346 void pushTimer(TimerIdT ID, TimerStackIdT StackID); |
| 367 void popTimer(TimerIdT ID, TimerStackIdT StackID); | 347 void popTimer(TimerIdT ID, TimerStackIdT StackID); |
| 368 void resetTimer(TimerStackIdT StackID); | 348 void resetTimer(TimerStackIdT StackID); |
| 369 void setTimerName(TimerStackIdT StackID, const IceString &NewName); | 349 void setTimerName(TimerStackIdT StackID, const std::string &NewName); |
| 370 | 350 |
| 371 /// This is the first work item sequence number that the parser produces, and | 351 /// This is the first work item sequence number that the parser produces, and |
| 372 /// correspondingly the first sequence number that the emitter thread will | 352 /// correspondingly the first sequence number that the emitter thread will |
| 373 /// wait for. Start numbering at 1 to leave room for a sentinel, in case e.g. | 353 /// wait for. Start numbering at 1 to leave room for a sentinel, in case e.g. |
| 374 /// we wish to inject items with a special sequence number that may be | 354 /// we wish to inject items with a special sequence number that may be |
| 375 /// executed out of order. | 355 /// executed out of order. |
| 376 static uint32_t getFirstSequenceNumber() { return 1; } | 356 static constexpr uint32_t getFirstSequenceNumber() { return 1; } |
| 377 /// Adds a newly parsed and constructed function to the Cfg work queue. | 357 /// Adds a newly parsed and constructed function to the Cfg work queue. |
| 378 /// Notifies any idle workers that a new function is available for | 358 /// Notifies any idle workers that a new function is available for |
| 379 /// translating. May block if the work queue is too large, in order to control | 359 /// translating. May block if the work queue is too large, in order to control |
| 380 /// memory footprint. | 360 /// memory footprint. |
| 381 void optQueueBlockingPush(std::unique_ptr<Cfg> Func); | 361 void optQueueBlockingPush(std::unique_ptr<Cfg> Func); |
| 382 /// Takes a Cfg from the work queue for translating. May block if the work | 362 /// Takes a Cfg from the work queue for translating. May block if the work |
| 383 /// queue is currently empty. Returns nullptr if there is no more work - the | 363 /// queue is currently empty. Returns nullptr if there is no more work - the |
| 384 /// queue is empty and either end() has been called or the Sequential flag was | 364 /// queue is empty and either end() has been called or the Sequential flag was |
| 385 /// set. | 365 /// set. |
| 386 std::unique_ptr<Cfg> optQueueBlockingPop(); | 366 std::unique_ptr<Cfg> optQueueBlockingPop(); |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 467 ICE_TLS_SET_FIELD(TLS, MyTLS); | 447 ICE_TLS_SET_FIELD(TLS, MyTLS); |
| 468 emitItems(); | 448 emitItems(); |
| 469 } | 449 } |
| 470 /// Emit functions and global initializers from the emitter queue until the | 450 /// Emit functions and global initializers from the emitter queue until the |
| 471 /// queue is empty. | 451 /// queue is empty. |
| 472 void emitItems(); | 452 void emitItems(); |
| 473 | 453 |
| 474 /// Uses DataLowering to lower Globals. Side effects: | 454 /// Uses DataLowering to lower Globals. Side effects: |
| 475 /// - discards the initializer list for the global variable in Globals. | 455 /// - discards the initializer list for the global variable in Globals. |
| 476 /// - clears the Globals array. | 456 /// - clears the Globals array. |
| 477 void lowerGlobals(const IceString &SectionSuffix); | 457 void lowerGlobals(const std::string &SectionSuffix); |
| 478 | 458 |
| 479 /// Lowers the profile information. | 459 /// Lowers the profile information. |
| 480 void lowerProfileData(); | 460 void lowerProfileData(); |
| 481 | 461 |
| 482 void dumpConstantLookupCounts(); | 462 void dumpConstantLookupCounts(); |
| 483 | 463 |
| 484 /// Utility function to match a symbol name against a match string. This is | 464 /// Utility function to match a symbol name against a match string. This is |
| 485 /// used in a few cases where we want to take some action on a particular | 465 /// used in a few cases where we want to take some action on a particular |
| 486 /// function or symbol based on a command-line argument, such as changing the | 466 /// function or symbol based on a command-line argument, such as changing the |
| 487 /// verbose level for a particular function. An empty Match argument means | 467 /// verbose level for a particular function. An empty Match argument means |
| 488 /// match everything. Returns true if there is a match. | 468 /// match everything. Returns true if there is a match. |
| 489 static bool matchSymbolName(const IceString &SymbolName, | 469 static bool matchSymbolName(const GlobalString &SymbolName, |
| 490 const IceString &Match) { | 470 const std::string &Match); |
| 491 return Match.empty() || Match == SymbolName; | |
| 492 } | |
| 493 | 471 |
| 494 static ClFlags Flags; | 472 static ClFlags Flags; |
| 495 | 473 |
| 496 /// DisposeGlobalVariablesAfterLowering controls whether the memory used by | 474 /// DisposeGlobalVariablesAfterLowering controls whether the memory used by |
| 497 /// GlobaleVariables can be reclaimed right after they have been lowered. | 475 /// GlobaleVariables can be reclaimed right after they have been lowered. |
| 498 /// @{ | 476 /// @{ |
| 499 bool getDisposeGlobalVariablesAfterLowering() const { | 477 bool getDisposeGlobalVariablesAfterLowering() const { |
| 500 return DisposeGlobalVariablesAfterLowering; | 478 return DisposeGlobalVariablesAfterLowering; |
| 501 } | 479 } |
| 502 | 480 |
| 503 void setDisposeGlobalVariablesAfterLowering(bool Value) { | 481 void setDisposeGlobalVariablesAfterLowering(bool Value) { |
| 504 DisposeGlobalVariablesAfterLowering = Value; | 482 DisposeGlobalVariablesAfterLowering = Value; |
| 505 } | 483 } |
| 506 /// @} | 484 /// @} |
| 507 | 485 |
| 486 LockedPtr<StringPool> getStrings() const { |
| 487 return LockedPtr<StringPool>(Strings.get(), &StringsLock); |
| 488 } |
| 489 |
| 508 private: | 490 private: |
| 509 // Try to ensure mutexes are allocated on separate cache lines. | 491 // Try to ensure mutexes are allocated on separate cache lines. |
| 510 | 492 |
| 511 // Destructors collaborate with Allocator | 493 // Destructors collaborate with Allocator |
| 512 ICE_CACHELINE_BOUNDARY; | 494 ICE_CACHELINE_BOUNDARY; |
| 513 // Managed by getAllocator() | 495 // Managed by getAllocator() |
| 514 GlobalLockType AllocLock; | 496 mutable GlobalLockType AllocLock; |
| 515 ArenaAllocator Allocator; | 497 ArenaAllocator Allocator; |
| 516 | 498 |
| 517 ICE_CACHELINE_BOUNDARY; | 499 ICE_CACHELINE_BOUNDARY; |
| 518 // Managed by getInitializerAllocator() | 500 // Managed by getInitializerAllocator() |
| 519 GlobalLockType InitAllocLock; | 501 mutable GlobalLockType InitAllocLock; |
| 520 VariableDeclarationList Globals; | 502 VariableDeclarationList Globals; |
| 521 | 503 |
| 522 ICE_CACHELINE_BOUNDARY; | 504 ICE_CACHELINE_BOUNDARY; |
| 523 // Managed by getDestructors() | 505 // Managed by getDestructors() |
| 524 using DestructorArray = std::vector<std::function<void()>>; | 506 using DestructorArray = std::vector<std::function<void()>>; |
| 525 GlobalLockType DestructorsLock; | 507 mutable GlobalLockType DestructorsLock; |
| 526 DestructorArray Destructors; | 508 DestructorArray Destructors; |
| 527 | 509 |
| 528 ICE_CACHELINE_BOUNDARY; | 510 ICE_CACHELINE_BOUNDARY; |
| 529 // Managed by getConstantPool() | 511 // Managed by getStrings() |
| 530 GlobalLockType ConstPoolLock; | 512 mutable GlobalLockType StringsLock; |
| 513 std::unique_ptr<StringPool> Strings; |
| 514 |
| 515 ICE_CACHELINE_BOUNDARY; |
| 516 // Managed by getConstPool() |
| 517 mutable GlobalLockType ConstPoolLock; |
| 531 std::unique_ptr<ConstantPool> ConstPool; | 518 std::unique_ptr<ConstantPool> ConstPool; |
| 532 | 519 |
| 533 ICE_CACHELINE_BOUNDARY; | 520 ICE_CACHELINE_BOUNDARY; |
| 534 // Managed by getJumpTableList() | 521 // Managed by getJumpTableList() |
| 535 GlobalLockType JumpTablesLock; | 522 mutable GlobalLockType JumpTablesLock; |
| 536 JumpTableDataList JumpTableList; | 523 JumpTableDataList JumpTableList; |
| 537 | 524 |
| 538 ICE_CACHELINE_BOUNDARY; | 525 ICE_CACHELINE_BOUNDARY; |
| 539 // Managed by getErrorStatus() | 526 // Managed by getErrorStatus() |
| 540 GlobalLockType ErrorStatusLock; | 527 mutable GlobalLockType ErrorStatusLock; |
| 541 ErrorCode ErrorStatus; | 528 ErrorCode ErrorStatus; |
| 542 | 529 |
| 543 ICE_CACHELINE_BOUNDARY; | 530 ICE_CACHELINE_BOUNDARY; |
| 544 // Managed by getStatsCumulative() | 531 // Managed by getStatsCumulative() |
| 545 GlobalLockType StatsLock; | 532 mutable GlobalLockType StatsLock; |
| 546 CodeStats StatsCumulative; | 533 CodeStats StatsCumulative; |
| 547 | 534 |
| 548 ICE_CACHELINE_BOUNDARY; | 535 ICE_CACHELINE_BOUNDARY; |
| 549 // Managed by getTimers() | 536 // Managed by getTimers() |
| 550 GlobalLockType TimerLock; | 537 mutable GlobalLockType TimerLock; |
| 551 TimerList Timers; | 538 TimerList Timers; |
| 552 | 539 |
| 553 ICE_CACHELINE_BOUNDARY; | 540 ICE_CACHELINE_BOUNDARY; |
| 554 /// StrLock is a global lock on the dump and emit output streams. | 541 /// StrLock is a global lock on the dump and emit output streams. |
| 555 using StrLockType = std::mutex; | 542 using StrLockType = std::mutex; |
| 556 StrLockType StrLock; | 543 StrLockType StrLock; |
| 557 Ostream *StrDump; /// Stream for dumping / diagnostics | 544 Ostream *StrDump; /// Stream for dumping / diagnostics |
| 558 Ostream *StrEmit; /// Stream for code emission | 545 Ostream *StrEmit; /// Stream for code emission |
| 559 Ostream *StrError; /// Stream for logging errors. | 546 Ostream *StrError; /// Stream for logging errors. |
| 560 | 547 |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 656 if (BuildDefs::timers()) | 643 if (BuildDefs::timers()) |
| 657 push(); | 644 push(); |
| 658 } | 645 } |
| 659 TimerMarker(TimerIdT ID, const Cfg *Func, | 646 TimerMarker(TimerIdT ID, const Cfg *Func, |
| 660 TimerStackIdT StackID = GlobalContext::TSK_Default) | 647 TimerStackIdT StackID = GlobalContext::TSK_Default) |
| 661 : ID(ID), Ctx(nullptr), StackID(StackID) { | 648 : ID(ID), Ctx(nullptr), StackID(StackID) { |
| 662 // Ctx gets set at the beginning of pushCfg(). | 649 // Ctx gets set at the beginning of pushCfg(). |
| 663 if (BuildDefs::timers()) | 650 if (BuildDefs::timers()) |
| 664 pushCfg(Func); | 651 pushCfg(Func); |
| 665 } | 652 } |
| 666 TimerMarker(GlobalContext *Ctx, const IceString &FuncName) | 653 TimerMarker(GlobalContext *Ctx, const std::string &FuncName) |
| 667 : ID(getTimerIdFromFuncName(Ctx, FuncName)), Ctx(Ctx), | 654 : ID(getTimerIdFromFuncName(Ctx, FuncName)), Ctx(Ctx), |
| 668 StackID(GlobalContext::TSK_Funcs) { | 655 StackID(GlobalContext::TSK_Funcs) { |
| 669 if (BuildDefs::timers()) | 656 if (BuildDefs::timers()) |
| 670 push(); | 657 push(); |
| 671 } | 658 } |
| 672 | 659 |
| 673 ~TimerMarker() { | 660 ~TimerMarker() { |
| 674 if (BuildDefs::timers() && Active) | 661 if (BuildDefs::timers() && Active) |
| 675 Ctx->popTimer(ID, StackID); | 662 Ctx->popTimer(ID, StackID); |
| 676 } | 663 } |
| 677 | 664 |
| 678 private: | 665 private: |
| 679 void push(); | 666 void push(); |
| 680 void pushCfg(const Cfg *Func); | 667 void pushCfg(const Cfg *Func); |
| 681 static TimerIdT getTimerIdFromFuncName(GlobalContext *Ctx, | 668 static TimerIdT getTimerIdFromFuncName(GlobalContext *Ctx, |
| 682 const IceString &FuncName); | 669 const std::string &FuncName); |
| 683 const TimerIdT ID; | 670 const TimerIdT ID; |
| 684 GlobalContext *Ctx; | 671 GlobalContext *Ctx; |
| 685 const TimerStackIdT StackID; | 672 const TimerStackIdT StackID; |
| 686 bool Active = false; | 673 bool Active = false; |
| 687 }; | 674 }; |
| 688 | 675 |
| 689 /// Helper class for locking the streams and then automatically unlocking them. | 676 /// Helper class for locking the streams and then automatically unlocking them. |
| 690 class OstreamLocker { | 677 class OstreamLocker { |
| 691 private: | 678 private: |
| 692 OstreamLocker() = delete; | 679 OstreamLocker() = delete; |
| 693 OstreamLocker(const OstreamLocker &) = delete; | 680 OstreamLocker(const OstreamLocker &) = delete; |
| 694 OstreamLocker &operator=(const OstreamLocker &) = delete; | 681 OstreamLocker &operator=(const OstreamLocker &) = delete; |
| 695 | 682 |
| 696 public: | 683 public: |
| 697 explicit OstreamLocker(GlobalContext *Ctx) : Ctx(Ctx) { Ctx->lockStr(); } | 684 explicit OstreamLocker(GlobalContext *Ctx) : Ctx(Ctx) { Ctx->lockStr(); } |
| 698 ~OstreamLocker() { Ctx->unlockStr(); } | 685 ~OstreamLocker() { Ctx->unlockStr(); } |
| 699 | 686 |
| 700 private: | 687 private: |
| 701 GlobalContext *const Ctx; | 688 GlobalContext *const Ctx; |
| 702 }; | 689 }; |
| 703 | 690 |
| 704 } // end of namespace Ice | 691 } // end of namespace Ice |
| 705 | 692 |
| 706 #endif // SUBZERO_SRC_ICEGLOBALCONTEXT_H | 693 #endif // SUBZERO_SRC_ICEGLOBALCONTEXT_H |
| OLD | NEW |