| 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 | 
|---|