Chromium Code Reviews| 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 137 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 148 ThreadContext() = default; | 148 ThreadContext() = default; |
| 149 CodeStats StatsFunction; | 149 CodeStats StatsFunction; |
| 150 CodeStats StatsCumulative; | 150 CodeStats StatsCumulative; |
| 151 TimerList Timers; | 151 TimerList Timers; |
| 152 }; | 152 }; |
| 153 | 153 |
| 154 public: | 154 public: |
| 155 /// The dump stream is a log stream while emit is the stream code | 155 /// The dump stream is a log stream while emit is the stream code |
| 156 /// is emitted to. The error stream is strictly for logging errors. | 156 /// is emitted to. The error stream is strictly for logging errors. |
| 157 GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError, | 157 GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError, |
| 158 ELFStreamer *ELFStreamer, const ClFlags &Flags); | 158 ELFStreamer *ELFStreamer); |
| 159 ~GlobalContext(); | 159 ~GlobalContext(); |
| 160 | 160 |
| 161 /// | 161 /// |
| 162 /// The dump, error, and emit streams need to be used by only one | 162 /// The dump, error, and emit streams need to be used by only one |
| 163 /// thread at a time. This is done by exclusively reserving the | 163 /// thread at a time. This is done by exclusively reserving the |
| 164 /// streams via lockStr() and unlockStr(). The OstreamLocker class | 164 /// streams via lockStr() and unlockStr(). The OstreamLocker class |
| 165 /// can be used to conveniently manage this. | 165 /// can be used to conveniently manage this. |
| 166 /// | 166 /// |
| 167 /// The model is that a thread grabs the stream lock, then does an | 167 /// The model is that a thread grabs the stream lock, then does an |
| 168 /// arbitrary amount of work during which far-away callees may grab | 168 /// arbitrary amount of work during which far-away callees may grab |
| 169 /// the stream and do something with it, and finally the thread | 169 /// the stream and do something with it, and finally the thread |
| 170 /// releases the stream lock. This allows large chunks of output to | 170 /// releases the stream lock. This allows large chunks of output to |
| 171 /// be dumped or emitted without risking interleaving from multiple | 171 /// be dumped or emitted without risking interleaving from multiple |
| 172 /// threads. | 172 /// threads. |
| 173 void lockStr() { StrLock.lock(); } | 173 void lockStr() { StrLock.lock(); } |
| 174 void unlockStr() { StrLock.unlock(); } | 174 void unlockStr() { StrLock.unlock(); } |
| 175 Ostream &getStrDump() { return *StrDump; } | 175 Ostream &getStrDump() { return *StrDump; } |
| 176 Ostream &getStrError() { return *StrError; } | 176 Ostream &getStrError() { return *StrError; } |
| 177 Ostream &getStrEmit() { return *StrEmit; } | 177 Ostream &getStrEmit() { return *StrEmit; } |
| 178 void setStrEmit(Ostream &NewStrEmit) { StrEmit = &NewStrEmit; } | 178 void setStrEmit(Ostream &NewStrEmit) { StrEmit = &NewStrEmit; } |
| 179 | 179 |
| 180 LockedPtr<ErrorCode> getErrorStatus() { | 180 LockedPtr<ErrorCode> getErrorStatus() { |
| 181 return LockedPtr<ErrorCode>(&ErrorStatus, &ErrorStatusLock); | 181 return LockedPtr<ErrorCode>(&ErrorStatus, &ErrorStatusLock); |
| 182 } | 182 } |
| 183 | 183 |
| 184 /// When emitting assembly, we allow a string to be prepended to | 184 /// When emitting assembly, we allow a string to be prepended to |
| 185 /// names of translated functions. This makes it easier to create an | 185 /// names of translated functions. This makes it easier to create an |
| 186 /// execution test against a reference translator like llc, with both | 186 /// execution test against a reference translator like llc, with both |
| 187 /// translators using the same bitcode as input. | 187 /// translators using the same bitcode as input. |
| 188 IceString mangleName(const IceString &Name) const; | 188 static IceString mangleName(const IceString &Name); |
|
John
2016/03/06 22:39:38
This declaration "smells". There's really no good
Jim Stichnoth
2016/03/07 00:03:10
Done - moved into new file IceMangling.cpp.
| |
| 189 | 189 |
| 190 /// \name Manage Constants. | 190 /// \name Manage Constants. |
| 191 /// @{ | 191 /// @{ |
| 192 // getConstant*() functions are not const because they might add something to | 192 // getConstant*() functions are not const because they might add something to |
| 193 // the constant pool. | 193 // the constant pool. |
| 194 Constant *getConstantInt(Type Ty, int64_t Value); | 194 Constant *getConstantInt(Type Ty, int64_t Value); |
| 195 Constant *getConstantInt1(int8_t ConstantInt1); | 195 Constant *getConstantInt1(int8_t ConstantInt1); |
| 196 Constant *getConstantInt8(int8_t ConstantInt8); | 196 Constant *getConstantInt8(int8_t ConstantInt8); |
| 197 Constant *getConstantInt16(int16_t ConstantInt16); | 197 Constant *getConstantInt16(int16_t ConstantInt16); |
| 198 Constant *getConstantInt32(int32_t ConstantInt32); | 198 Constant *getConstantInt32(int32_t ConstantInt32); |
| 199 Constant *getConstantInt64(int64_t ConstantInt64); | 199 Constant *getConstantInt64(int64_t ConstantInt64); |
| 200 Constant *getConstantFloat(float Value); | 200 Constant *getConstantFloat(float Value); |
| 201 Constant *getConstantDouble(double Value); | 201 Constant *getConstantDouble(double Value); |
| 202 /// Returns a symbolic constant. | 202 /// Returns a symbolic constant. |
| 203 Constant *getConstantSym(const RelocOffsetT Offset, | 203 Constant *getConstantSym(const RelocOffsetT Offset, |
| 204 const RelocOffsetArray &OffsetExpr, | 204 const RelocOffsetArray &OffsetExpr, |
| 205 const IceString &Name, const IceString &EmitString, | 205 const IceString &Name, const IceString &EmitString); |
| 206 bool SuppressMangling); | 206 Constant *getConstantSym(RelocOffsetT Offset, const IceString &Name); |
| 207 Constant *getConstantSym(RelocOffsetT Offset, const IceString &Name, | |
| 208 bool SuppressMangling); | |
| 209 Constant *getConstantExternSym(const IceString &Name); | 207 Constant *getConstantExternSym(const IceString &Name); |
| 210 /// Returns an undef. | 208 /// Returns an undef. |
| 211 Constant *getConstantUndef(Type Ty); | 209 Constant *getConstantUndef(Type Ty); |
| 212 /// Returns a zero value. | 210 /// Returns a zero value. |
| 213 Constant *getConstantZero(Type Ty); | 211 Constant *getConstantZero(Type Ty); |
| 214 /// getConstantPool() returns a copy of the constant pool for constants of a | 212 /// getConstantPool() returns a copy of the constant pool for constants of a |
| 215 /// given type. | 213 /// given type. |
| 216 ConstantList getConstantPool(Type Ty); | 214 ConstantList getConstantPool(Type Ty); |
| 217 /// Returns a copy of the list of external symbols. | 215 /// Returns a copy of the list of external symbols. |
| 218 ConstantList getConstantExternSyms(); | 216 ConstantList getConstantExternSyms(); |
| 219 /// @} | 217 /// @} |
| 220 | 218 |
| 221 /// Return a locked pointer to the registered jump tables. | 219 /// Return a locked pointer to the registered jump tables. |
| 222 JumpTableDataList getJumpTables(); | 220 JumpTableDataList getJumpTables(); |
| 223 /// Create a new jump table entry and return a reference to it. | 221 /// Create a new jump table entry and return a reference to it. |
| 224 JumpTableData &addJumpTable(IceString FuncName, SizeT Id, | 222 JumpTableData &addJumpTable(const IceString &FuncName, SizeT Id, |
| 225 const JumpTableData::TargetList &TargetList); | 223 const JumpTableData::TargetList &TargetList); |
| 226 | 224 |
| 227 const ClFlags &getFlags() const { return Flags; } | 225 static const ClFlags &getFlags() { return Flags; } |
|
John
2016/03/06 22:39:38
Ditto.
Jim Stichnoth
2016/03/07 00:03:10
I assume this is about flags being global, in whic
| |
| 228 | 226 |
| 229 /// Allocate data of type T using the global allocator. We allow entities | 227 /// Allocate data of type T using the global allocator. We allow entities |
| 230 /// allocated from this global allocator to be either trivially or | 228 /// allocated from this global allocator to be either trivially or |
| 231 /// non-trivially destructible. We optimize the case when T is trivially | 229 /// non-trivially destructible. We optimize the case when T is trivially |
| 232 /// destructible by not registering a destructor. Destructors will be invoked | 230 /// destructible by not registering a destructor. Destructors will be invoked |
| 233 /// during GlobalContext destruction in the reverse object creation order. | 231 /// during GlobalContext destruction in the reverse object creation order. |
| 234 template <typename T> | 232 template <typename T> |
| 235 typename std::enable_if<std::is_trivially_destructible<T>::value, T>::type * | 233 typename std::enable_if<std::is_trivially_destructible<T>::value, T>::type * |
| 236 allocate() { | 234 allocate() { |
| 237 return getAllocator()->Allocate<T>(); | 235 return getAllocator()->Allocate<T>(); |
| (...skipping 193 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 431 /// Utility function to match a symbol name against a match string. This is | 429 /// Utility function to match a symbol name against a match string. This is |
| 432 /// used in a few cases where we want to take some action on a particular | 430 /// used in a few cases where we want to take some action on a particular |
| 433 /// function or symbol based on a command-line argument, such as changing the | 431 /// function or symbol based on a command-line argument, such as changing the |
| 434 /// verbose level for a particular function. An empty Match argument means | 432 /// verbose level for a particular function. An empty Match argument means |
| 435 /// match everything. Returns true if there is a match. | 433 /// match everything. Returns true if there is a match. |
| 436 static bool matchSymbolName(const IceString &SymbolName, | 434 static bool matchSymbolName(const IceString &SymbolName, |
| 437 const IceString &Match) { | 435 const IceString &Match) { |
| 438 return Match.empty() || Match == SymbolName; | 436 return Match.empty() || Match == SymbolName; |
| 439 } | 437 } |
| 440 | 438 |
| 439 static ClFlags Flags; | |
| 440 static ClFlagsExtra ExtraFlags; | |
| 441 | |
| 441 private: | 442 private: |
| 442 // Try to ensure mutexes are allocated on separate cache lines. | 443 // Try to ensure mutexes are allocated on separate cache lines. |
| 443 | 444 |
| 444 // Destructors collaborate with Allocator | 445 // Destructors collaborate with Allocator |
| 445 ICE_CACHELINE_BOUNDARY; | 446 ICE_CACHELINE_BOUNDARY; |
| 446 // Managed by getAllocator() | 447 // Managed by getAllocator() |
| 447 GlobalLockType AllocLock; | 448 GlobalLockType AllocLock; |
| 448 ArenaAllocator Allocator; | 449 ArenaAllocator Allocator; |
| 449 | 450 |
| 450 ICE_CACHELINE_BOUNDARY; | 451 ICE_CACHELINE_BOUNDARY; |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 482 /// StrLock is a global lock on the dump and emit output streams. | 483 /// StrLock is a global lock on the dump and emit output streams. |
| 483 using StrLockType = std::mutex; | 484 using StrLockType = std::mutex; |
| 484 StrLockType StrLock; | 485 StrLockType StrLock; |
| 485 Ostream *StrDump; /// Stream for dumping / diagnostics | 486 Ostream *StrDump; /// Stream for dumping / diagnostics |
| 486 Ostream *StrEmit; /// Stream for code emission | 487 Ostream *StrEmit; /// Stream for code emission |
| 487 Ostream *StrError; /// Stream for logging errors. | 488 Ostream *StrError; /// Stream for logging errors. |
| 488 | 489 |
| 489 ICE_CACHELINE_BOUNDARY; | 490 ICE_CACHELINE_BOUNDARY; |
| 490 | 491 |
| 491 Intrinsics IntrinsicsInfo; | 492 Intrinsics IntrinsicsInfo; |
| 492 const ClFlags &Flags; | |
| 493 // TODO(jpp): move to EmitterContext. | 493 // TODO(jpp): move to EmitterContext. |
| 494 std::unique_ptr<ELFObjectWriter> ObjectWriter; | 494 std::unique_ptr<ELFObjectWriter> ObjectWriter; |
| 495 BoundedProducerConsumerQueue<Cfg> OptQ; | 495 BoundedProducerConsumerQueue<Cfg> OptQ; |
| 496 BoundedProducerConsumerQueue<EmitterWorkItem> EmitQ; | 496 BoundedProducerConsumerQueue<EmitterWorkItem> EmitQ; |
| 497 // DataLowering is only ever used by a single thread at a time (either in | 497 // DataLowering is only ever used by a single thread at a time (either in |
| 498 // emitItems(), or in IceCompiler::run before the compilation is over.) | 498 // emitItems(), or in IceCompiler::run before the compilation is over.) |
| 499 // TODO(jpp): move to EmitterContext. | 499 // TODO(jpp): move to EmitterContext. |
| 500 std::unique_ptr<TargetDataLowering> DataLowering; | 500 std::unique_ptr<TargetDataLowering> DataLowering; |
| 501 /// If !HasEmittedCode, SubZero will accumulate all Globals (which are "true" | 501 /// If !HasEmittedCode, SubZero will accumulate all Globals (which are "true" |
| 502 /// program global variables) until the first code WorkItem is seen. | 502 /// program global variables) until the first code WorkItem is seen. |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 543 | 543 |
| 544 llvm::SmallVector<ThreadContext *, 128> AllThreadContexts; | 544 llvm::SmallVector<ThreadContext *, 128> AllThreadContexts; |
| 545 llvm::SmallVector<std::thread, 128> TranslationThreads; | 545 llvm::SmallVector<std::thread, 128> TranslationThreads; |
| 546 llvm::SmallVector<std::thread, 128> EmitterThreads; | 546 llvm::SmallVector<std::thread, 128> EmitterThreads; |
| 547 // Each thread has its own TLS pointer which is also held in | 547 // Each thread has its own TLS pointer which is also held in |
| 548 // AllThreadContexts. | 548 // AllThreadContexts. |
| 549 ICE_TLS_DECLARE_FIELD(ThreadContext *, TLS); | 549 ICE_TLS_DECLARE_FIELD(ThreadContext *, TLS); |
| 550 | 550 |
| 551 // Private helpers for mangleName() | 551 // Private helpers for mangleName() |
| 552 using ManglerVector = llvm::SmallVector<char, 32>; | 552 using ManglerVector = llvm::SmallVector<char, 32>; |
| 553 void incrementSubstitutions(ManglerVector &OldName) const; | 553 static void incrementSubstitutions(ManglerVector &OldName); |
| 554 | 554 |
| 555 public: | 555 public: |
| 556 static void TlsInit() { ICE_TLS_INIT_FIELD(TLS); } | 556 static void TlsInit() { ICE_TLS_INIT_FIELD(TLS); } |
| 557 }; | 557 }; |
| 558 | 558 |
| 559 /// Helper class to push and pop a timer marker. The constructor pushes a | 559 /// Helper class to push and pop a timer marker. The constructor pushes a |
| 560 /// marker, and the destructor pops it. This is for convenient timing of regions | 560 /// marker, and the destructor pops it. This is for convenient timing of regions |
| 561 /// of code. | 561 /// of code. |
| 562 class TimerMarker { | 562 class TimerMarker { |
| 563 TimerMarker() = delete; | 563 TimerMarker() = delete; |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 604 explicit OstreamLocker(GlobalContext *Ctx) : Ctx(Ctx) { Ctx->lockStr(); } | 604 explicit OstreamLocker(GlobalContext *Ctx) : Ctx(Ctx) { Ctx->lockStr(); } |
| 605 ~OstreamLocker() { Ctx->unlockStr(); } | 605 ~OstreamLocker() { Ctx->unlockStr(); } |
| 606 | 606 |
| 607 private: | 607 private: |
| 608 GlobalContext *const Ctx; | 608 GlobalContext *const Ctx; |
| 609 }; | 609 }; |
| 610 | 610 |
| 611 } // end of namespace Ice | 611 } // end of namespace Ice |
| 612 | 612 |
| 613 #endif // SUBZERO_SRC_ICEGLOBALCONTEXT_H | 613 #endif // SUBZERO_SRC_ICEGLOBALCONTEXT_H |
| OLD | NEW |