Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(11)

Side by Side Diff: src/IceGlobalContext.h

Issue 1216963007: Doxygenize the documentation comments (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 // This file declares aspects of the compilation that persist across 10 // This file declares aspects of the compilation that persist across
(...skipping 20 matching lines...) Expand all
31 #include <type_traits> 31 #include <type_traits>
32 #include <vector> 32 #include <vector>
33 33
34 namespace Ice { 34 namespace Ice {
35 35
36 class ClFlags; 36 class ClFlags;
37 class ConstantPool; 37 class ConstantPool;
38 class EmitterWorkItem; 38 class EmitterWorkItem;
39 class FuncSigType; 39 class FuncSigType;
40 40
41 // LockedPtr is a way to provide automatically locked access to some object. 41 /// LockedPtr is a way to provide automatically locked access to some object.
42 template <typename T> class LockedPtr { 42 template <typename T> class LockedPtr {
43 LockedPtr() = delete; 43 LockedPtr() = delete;
44 LockedPtr(const LockedPtr &) = delete; 44 LockedPtr(const LockedPtr &) = delete;
45 LockedPtr &operator=(const LockedPtr &) = delete; 45 LockedPtr &operator=(const LockedPtr &) = delete;
46 46
47 public: 47 public:
48 LockedPtr(T *Value, GlobalLockType *Lock) : Value(Value), Lock(Lock) { 48 LockedPtr(T *Value, GlobalLockType *Lock) : Value(Value), Lock(Lock) {
49 Lock->lock(); 49 Lock->lock();
50 } 50 }
51 LockedPtr(LockedPtr &&Other) : Value(Other.Value), Lock(Other.Lock) { 51 LockedPtr(LockedPtr &&Other) : Value(Other.Value), Lock(Other.Lock) {
52 Other.Value = nullptr; 52 Other.Value = nullptr;
53 Other.Lock = nullptr; 53 Other.Lock = nullptr;
54 } 54 }
55 ~LockedPtr() { Lock->unlock(); } 55 ~LockedPtr() { Lock->unlock(); }
56 T *operator->() const { return Value; } 56 T *operator->() const { return Value; }
57 57
58 private: 58 private:
59 T *Value; 59 T *Value;
60 GlobalLockType *Lock; 60 GlobalLockType *Lock;
61 }; 61 };
62 62
63 class GlobalContext { 63 class GlobalContext {
64 GlobalContext() = delete; 64 GlobalContext() = delete;
65 GlobalContext(const GlobalContext &) = delete; 65 GlobalContext(const GlobalContext &) = delete;
66 GlobalContext &operator=(const GlobalContext &) = delete; 66 GlobalContext &operator=(const GlobalContext &) = delete;
67 67
68 // CodeStats collects rudimentary statistics during translation. 68 /// CodeStats collects rudimentary statistics during translation.
69 class CodeStats { 69 class CodeStats {
70 CodeStats(const CodeStats &) = delete; 70 CodeStats(const CodeStats &) = delete;
71 CodeStats &operator=(const CodeStats &) = default; 71 CodeStats &operator=(const CodeStats &) = default;
72 #define CODESTATS_TABLE \ 72 #define CODESTATS_TABLE \
73 /* dump string, enum value */ \ 73 /* dump string, enum value */ \
74 X("Inst Count ", InstCount) \ 74 X("Inst Count ", InstCount) \
75 X("Regs Saved ", RegsSaved) \ 75 X("Regs Saved ", RegsSaved) \
76 X("Frame Bytes ", FrameByte) \ 76 X("Frame Bytes ", FrameByte) \
77 X("Spills ", NumSpills) \ 77 X("Spills ", NumSpills) \
78 X("Fills ", NumFills) \ 78 X("Fills ", NumFills) \
(...skipping 16 matching lines...) Expand all
95 void add(const CodeStats &Other) { 95 void add(const CodeStats &Other) {
96 for (uint32_t i = 0; i < Stats.size(); ++i) 96 for (uint32_t i = 0; i < Stats.size(); ++i)
97 Stats[i] += Other.Stats[i]; 97 Stats[i] += Other.Stats[i];
98 } 98 }
99 void dump(const IceString &Name, Ostream &Str); 99 void dump(const IceString &Name, Ostream &Str);
100 100
101 private: 101 private:
102 std::array<uint32_t, CS_NUM> Stats; 102 std::array<uint32_t, CS_NUM> Stats;
103 }; 103 };
104 104
105 // TimerList is a vector of TimerStack objects, with extra methods 105 /// TimerList is a vector of TimerStack objects, with extra methods
106 // to initialize and merge these vectors. 106 /// to initialize and merge these vectors.
107 class TimerList : public std::vector<TimerStack> { 107 class TimerList : public std::vector<TimerStack> {
108 TimerList(const TimerList &) = delete; 108 TimerList(const TimerList &) = delete;
109 TimerList &operator=(const TimerList &) = delete; 109 TimerList &operator=(const TimerList &) = delete;
110 110
111 public: 111 public:
112 TimerList() = default; 112 TimerList() = default;
113 // initInto() initializes a target list of timers based on the 113 /// initInto() initializes a target list of timers based on the
114 // current list. In particular, it creates the same number of 114 /// current list. In particular, it creates the same number of
115 // timers, in the same order, with the same names, but initially 115 /// timers, in the same order, with the same names, but initially
116 // empty of timing data. 116 /// empty of timing data.
117 void initInto(TimerList &Dest) const { 117 void initInto(TimerList &Dest) const {
118 if (!BuildDefs::dump()) 118 if (!BuildDefs::dump())
119 return; 119 return;
120 Dest.clear(); 120 Dest.clear();
121 for (const TimerStack &Stack : *this) { 121 for (const TimerStack &Stack : *this) {
122 Dest.push_back(TimerStack(Stack.getName())); 122 Dest.push_back(TimerStack(Stack.getName()));
123 } 123 }
124 } 124 }
125 void mergeFrom(TimerList &Src) { 125 void mergeFrom(TimerList &Src) {
126 if (!BuildDefs::dump()) 126 if (!BuildDefs::dump())
127 return; 127 return;
128 assert(size() == Src.size()); 128 assert(size() == Src.size());
129 size_type i = 0; 129 size_type i = 0;
130 for (TimerStack &Stack : *this) { 130 for (TimerStack &Stack : *this) {
131 assert(Stack.getName() == Src[i].getName()); 131 assert(Stack.getName() == Src[i].getName());
132 Stack.mergeFrom(Src[i]); 132 Stack.mergeFrom(Src[i]);
133 ++i; 133 ++i;
134 } 134 }
135 } 135 }
136 }; 136 };
137 137
138 // ThreadContext contains thread-local data. This data can be 138 /// ThreadContext contains thread-local data. This data can be
139 // combined/reduced as needed after all threads complete. 139 /// combined/reduced as needed after all threads complete.
140 class ThreadContext { 140 class ThreadContext {
141 ThreadContext(const ThreadContext &) = delete; 141 ThreadContext(const ThreadContext &) = delete;
142 ThreadContext &operator=(const ThreadContext &) = delete; 142 ThreadContext &operator=(const ThreadContext &) = delete;
143 143
144 public: 144 public:
145 ThreadContext() = default; 145 ThreadContext() = default;
146 CodeStats StatsFunction; 146 CodeStats StatsFunction;
147 CodeStats StatsCumulative; 147 CodeStats StatsCumulative;
148 TimerList Timers; 148 TimerList Timers;
149 }; 149 };
150 150
151 public: 151 public:
152 // The dump stream is a log stream while emit is the stream code 152 /// The dump stream is a log stream while emit is the stream code
153 // is emitted to. The error stream is strictly for logging errors. 153 /// is emitted to. The error stream is strictly for logging errors.
154 GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError, 154 GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError,
155 ELFStreamer *ELFStreamer, const ClFlags &Flags); 155 ELFStreamer *ELFStreamer, const ClFlags &Flags);
156 ~GlobalContext(); 156 ~GlobalContext();
157 157
158 // 158 ///
159 // The dump, error, and emit streams need to be used by only one 159 /// The dump, error, and emit streams need to be used by only one
160 // thread at a time. This is done by exclusively reserving the 160 /// thread at a time. This is done by exclusively reserving the
161 // streams via lockStr() and unlockStr(). The OstreamLocker class 161 /// streams via lockStr() and unlockStr(). The OstreamLocker class
162 // can be used to conveniently manage this. 162 /// can be used to conveniently manage this.
163 // 163 ///
164 // The model is that a thread grabs the stream lock, then does an 164 /// The model is that a thread grabs the stream lock, then does an
165 // arbitrary amount of work during which far-away callees may grab 165 /// arbitrary amount of work during which far-away callees may grab
166 // the stream and do something with it, and finally the thread 166 /// the stream and do something with it, and finally the thread
167 // releases the stream lock. This allows large chunks of output to 167 /// releases the stream lock. This allows large chunks of output to
168 // be dumped or emitted without risking interleaving from multiple 168 /// be dumped or emitted without risking interleaving from multiple
169 // threads. 169 /// threads.
170 void lockStr() { StrLock.lock(); } 170 void lockStr() { StrLock.lock(); }
171 void unlockStr() { StrLock.unlock(); } 171 void unlockStr() { StrLock.unlock(); }
172 Ostream &getStrDump() { return *StrDump; } 172 Ostream &getStrDump() { return *StrDump; }
173 Ostream &getStrError() { return *StrError; } 173 Ostream &getStrError() { return *StrError; }
174 Ostream &getStrEmit() { return *StrEmit; } 174 Ostream &getStrEmit() { return *StrEmit; }
175 175
176 LockedPtr<ErrorCode> getErrorStatus() { 176 LockedPtr<ErrorCode> getErrorStatus() {
177 return LockedPtr<ErrorCode>(&ErrorStatus, &ErrorStatusLock); 177 return LockedPtr<ErrorCode>(&ErrorStatus, &ErrorStatusLock);
178 } 178 }
179 179
180 // When emitting assembly, we allow a string to be prepended to 180 /// When emitting assembly, we allow a string to be prepended to
181 // names of translated functions. This makes it easier to create an 181 /// names of translated functions. This makes it easier to create an
182 // execution test against a reference translator like llc, with both 182 /// execution test against a reference translator like llc, with both
183 // translators using the same bitcode as input. 183 /// translators using the same bitcode as input.
184 IceString mangleName(const IceString &Name) const; 184 IceString mangleName(const IceString &Name) const;
185 185
186 // Manage Constants. 186 // Manage Constants.
187 // getConstant*() functions are not const because they might add 187 // getConstant*() functions are not const because they might add
188 // something to the constant pool. 188 // something to the constant pool.
189 Constant *getConstantInt(Type Ty, int64_t Value); 189 Constant *getConstantInt(Type Ty, int64_t Value);
190 Constant *getConstantInt1(int8_t ConstantInt1); 190 Constant *getConstantInt1(int8_t ConstantInt1);
191 Constant *getConstantInt8(int8_t ConstantInt8); 191 Constant *getConstantInt8(int8_t ConstantInt8);
192 Constant *getConstantInt16(int16_t ConstantInt16); 192 Constant *getConstantInt16(int16_t ConstantInt16);
193 Constant *getConstantInt32(int32_t ConstantInt32); 193 Constant *getConstantInt32(int32_t ConstantInt32);
194 Constant *getConstantInt64(int64_t ConstantInt64); 194 Constant *getConstantInt64(int64_t ConstantInt64);
195 Constant *getConstantFloat(float Value); 195 Constant *getConstantFloat(float Value);
196 Constant *getConstantDouble(double Value); 196 Constant *getConstantDouble(double Value);
197 // Returns a symbolic constant. 197 /// Returns a symbolic constant.
198 Constant *getConstantSym(RelocOffsetT Offset, const IceString &Name, 198 Constant *getConstantSym(RelocOffsetT Offset, const IceString &Name,
199 bool SuppressMangling); 199 bool SuppressMangling);
200 Constant *getConstantExternSym(const IceString &Name); 200 Constant *getConstantExternSym(const IceString &Name);
201 // Returns an undef. 201 /// Returns an undef.
202 Constant *getConstantUndef(Type Ty); 202 Constant *getConstantUndef(Type Ty);
203 // Returns a zero value. 203 /// Returns a zero value.
204 Constant *getConstantZero(Type Ty); 204 Constant *getConstantZero(Type Ty);
205 // getConstantPool() returns a copy of the constant pool for 205 /// getConstantPool() returns a copy of the constant pool for
206 // constants of a given type. 206 /// constants of a given type.
207 ConstantList getConstantPool(Type Ty); 207 ConstantList getConstantPool(Type Ty);
208 // Returns a copy of the list of external symbols. 208 /// Returns a copy of the list of external symbols.
209 ConstantList getConstantExternSyms(); 209 ConstantList getConstantExternSyms();
210 210
211 const ClFlags &getFlags() const { return Flags; } 211 const ClFlags &getFlags() const { return Flags; }
212 212
213 bool isIRGenerationDisabled() const { 213 bool isIRGenerationDisabled() const {
214 return getFlags().getDisableIRGeneration(); 214 return getFlags().getDisableIRGeneration();
215 } 215 }
216 216
217 // Allocate data of type T using the global allocator. We allow entities 217 /// Allocate data of type T using the global allocator. We allow entities
218 // allocated from this global allocator to be either trivially or 218 /// allocated from this global allocator to be either trivially or
219 // non-trivially destructible. We optimize the case when T is trivially 219 /// non-trivially destructible. We optimize the case when T is trivially
220 // destructible by not registering a destructor. Destructors will be invoked 220 /// destructible by not registering a destructor. Destructors will be invoked
221 // during GlobalContext destruction in the reverse object creation order. 221 /// during GlobalContext destruction in the reverse object creation order.
222 template <typename T> 222 template <typename T>
223 typename std::enable_if<std::is_trivially_destructible<T>::value, T>::type * 223 typename std::enable_if<std::is_trivially_destructible<T>::value, T>::type *
224 allocate() { 224 allocate() {
225 return getAllocator()->Allocate<T>(); 225 return getAllocator()->Allocate<T>();
226 } 226 }
227 227
228 template <typename T> 228 template <typename T>
229 typename std::enable_if<!std::is_trivially_destructible<T>::value, T>::type * 229 typename std::enable_if<!std::is_trivially_destructible<T>::value, T>::type *
230 allocate() { 230 allocate() {
231 T *Ret = getAllocator()->Allocate<T>(); 231 T *Ret = getAllocator()->Allocate<T>();
232 getDestructors()->emplace_back([Ret]() { Ret->~T(); }); 232 getDestructors()->emplace_back([Ret]() { Ret->~T(); });
233 return Ret; 233 return Ret;
234 } 234 }
235 235
236 const Intrinsics &getIntrinsicsInfo() const { return IntrinsicsInfo; } 236 const Intrinsics &getIntrinsicsInfo() const { return IntrinsicsInfo; }
237 237
238 // TODO(wala,stichnot): Make the RNG play nicely with multithreaded 238 // TODO(wala,stichnot): Make the RNG play nicely with multithreaded
239 // translation. 239 // translation.
240 RandomNumberGenerator &getRNG() { return RNG; } 240 RandomNumberGenerator &getRNG() { return RNG; }
241 241
242 ELFObjectWriter *getObjectWriter() const { return ObjectWriter.get(); } 242 ELFObjectWriter *getObjectWriter() const { return ObjectWriter.get(); }
243 243
244 // Reset stats at the beginning of a function. 244 /// Reset stats at the beginning of a function.
245 void resetStats() { 245 void resetStats() {
246 if (BuildDefs::dump()) 246 if (BuildDefs::dump())
247 ICE_TLS_GET_FIELD(TLS)->StatsFunction.reset(); 247 ICE_TLS_GET_FIELD(TLS)->StatsFunction.reset();
248 } 248 }
249 void dumpStats(const IceString &Name, bool Final = false); 249 void dumpStats(const IceString &Name, bool Final = false);
250 void statsUpdateEmitted(uint32_t InstCount) { 250 void statsUpdateEmitted(uint32_t InstCount) {
251 if (!getFlags().getDumpStats()) 251 if (!getFlags().getDumpStats())
252 return; 252 return;
253 ThreadContext *Tls = ICE_TLS_GET_FIELD(TLS); 253 ThreadContext *Tls = ICE_TLS_GET_FIELD(TLS);
254 Tls->StatsFunction.update(CodeStats::CS_InstCount, InstCount); 254 Tls->StatsFunction.update(CodeStats::CS_InstCount, InstCount);
(...skipping 21 matching lines...) Expand all
276 Tls->StatsCumulative.update(CodeStats::CS_NumSpills); 276 Tls->StatsCumulative.update(CodeStats::CS_NumSpills);
277 } 277 }
278 void statsUpdateFills() { 278 void statsUpdateFills() {
279 if (!getFlags().getDumpStats()) 279 if (!getFlags().getDumpStats())
280 return; 280 return;
281 ThreadContext *Tls = ICE_TLS_GET_FIELD(TLS); 281 ThreadContext *Tls = ICE_TLS_GET_FIELD(TLS);
282 Tls->StatsFunction.update(CodeStats::CS_NumFills); 282 Tls->StatsFunction.update(CodeStats::CS_NumFills);
283 Tls->StatsCumulative.update(CodeStats::CS_NumFills); 283 Tls->StatsCumulative.update(CodeStats::CS_NumFills);
284 } 284 }
285 285
286 // Number of Randomized or Pooled Immediates 286 /// Number of Randomized or Pooled Immediates
287 void statsUpdateRPImms() { 287 void statsUpdateRPImms() {
288 if (!getFlags().getDumpStats()) 288 if (!getFlags().getDumpStats())
289 return; 289 return;
290 ThreadContext *Tls = ICE_TLS_GET_FIELD(TLS); 290 ThreadContext *Tls = ICE_TLS_GET_FIELD(TLS);
291 Tls->StatsFunction.update(CodeStats::CS_NumRPImms); 291 Tls->StatsFunction.update(CodeStats::CS_NumRPImms);
292 Tls->StatsCumulative.update(CodeStats::CS_NumRPImms); 292 Tls->StatsCumulative.update(CodeStats::CS_NumRPImms);
293 } 293 }
294 294
295 // These are predefined TimerStackIdT values. 295 /// These are predefined TimerStackIdT values.
296 enum TimerStackKind { TSK_Default = 0, TSK_Funcs, TSK_Num }; 296 enum TimerStackKind { TSK_Default = 0, TSK_Funcs, TSK_Num };
297 297
298 // newTimerStackID() creates a new TimerStack in the global space. 298 /// newTimerStackID() creates a new TimerStack in the global space.
299 // It does not affect any TimerStack objects in TLS. 299 /// It does not affect any TimerStack objects in TLS.
300 TimerStackIdT newTimerStackID(const IceString &Name); 300 TimerStackIdT newTimerStackID(const IceString &Name);
301 // dumpTimers() dumps the global timer data. As such, one probably 301 /// dumpTimers() dumps the global timer data. As such, one probably
302 // wants to call mergeTimerStacks() as a prerequisite. 302 /// wants to call mergeTimerStacks() as a prerequisite.
303 void dumpTimers(TimerStackIdT StackID = TSK_Default, 303 void dumpTimers(TimerStackIdT StackID = TSK_Default,
304 bool DumpCumulative = true); 304 bool DumpCumulative = true);
305 // The following methods affect only the calling thread's TLS timer 305 /// The following methods affect only the calling thread's TLS timer
306 // data. 306 /// data.
307 TimerIdT getTimerID(TimerStackIdT StackID, const IceString &Name); 307 TimerIdT getTimerID(TimerStackIdT StackID, const IceString &Name);
308 void pushTimer(TimerIdT ID, TimerStackIdT StackID); 308 void pushTimer(TimerIdT ID, TimerStackIdT StackID);
309 void popTimer(TimerIdT ID, TimerStackIdT StackID); 309 void popTimer(TimerIdT ID, TimerStackIdT StackID);
310 void resetTimer(TimerStackIdT StackID); 310 void resetTimer(TimerStackIdT StackID);
311 void setTimerName(TimerStackIdT StackID, const IceString &NewName); 311 void setTimerName(TimerStackIdT StackID, const IceString &NewName);
312 312
313 // This is the first work item sequence number that the parser 313 /// This is the first work item sequence number that the parser
314 // produces, and correspondingly the first sequence number that the 314 /// produces, and correspondingly the first sequence number that the
315 // emitter thread will wait for. Start numbering at 1 to leave room 315 /// emitter thread will wait for. Start numbering at 1 to leave room
316 // for a sentinel, in case e.g. we wish to inject items with a 316 /// for a sentinel, in case e.g. we wish to inject items with a
317 // special sequence number that may be executed out of order. 317 /// special sequence number that may be executed out of order.
318 static uint32_t getFirstSequenceNumber() { return 1; } 318 static uint32_t getFirstSequenceNumber() { return 1; }
319 // Adds a newly parsed and constructed function to the Cfg work 319 /// Adds a newly parsed and constructed function to the Cfg work
320 // queue. Notifies any idle workers that a new function is 320 /// queue. Notifies any idle workers that a new function is
321 // available for translating. May block if the work queue is too 321 /// available for translating. May block if the work queue is too
322 // large, in order to control memory footprint. 322 /// large, in order to control memory footprint.
323 void optQueueBlockingPush(std::unique_ptr<Cfg> Func); 323 void optQueueBlockingPush(std::unique_ptr<Cfg> Func);
324 // Takes a Cfg from the work queue for translating. May block if 324 /// Takes a Cfg from the work queue for translating. May block if
325 // the work queue is currently empty. Returns nullptr if there is 325 /// the work queue is currently empty. Returns nullptr if there is
326 // no more work - the queue is empty and either end() has been 326 /// no more work - the queue is empty and either end() has been
327 // called or the Sequential flag was set. 327 /// called or the Sequential flag was set.
328 std::unique_ptr<Cfg> optQueueBlockingPop(); 328 std::unique_ptr<Cfg> optQueueBlockingPop();
329 // Notifies that no more work will be added to the work queue. 329 /// Notifies that no more work will be added to the work queue.
330 void optQueueNotifyEnd() { OptQ.notifyEnd(); } 330 void optQueueNotifyEnd() { OptQ.notifyEnd(); }
331 331
332 // Emit file header for output file. 332 /// Emit file header for output file.
333 void emitFileHeader(); 333 void emitFileHeader();
334 334
335 void lowerConstants(); 335 void lowerConstants();
336 336
337 void emitQueueBlockingPush(EmitterWorkItem *Item); 337 void emitQueueBlockingPush(EmitterWorkItem *Item);
338 EmitterWorkItem *emitQueueBlockingPop(); 338 EmitterWorkItem *emitQueueBlockingPop();
339 void emitQueueNotifyEnd() { EmitQ.notifyEnd(); } 339 void emitQueueNotifyEnd() { EmitQ.notifyEnd(); }
340 340
341 void initParserThread() { 341 void initParserThread() {
342 ThreadContext *Tls = new ThreadContext(); 342 ThreadContext *Tls = new ThreadContext();
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
387 } 387 }
388 if (BuildDefs::dump()) { 388 if (BuildDefs::dump()) {
389 // Do a separate loop over AllThreadContexts to avoid holding 389 // Do a separate loop over AllThreadContexts to avoid holding
390 // two locks at once. 390 // two locks at once.
391 auto Stats = getStatsCumulative(); 391 auto Stats = getStatsCumulative();
392 for (ThreadContext *TLS : AllThreadContexts) 392 for (ThreadContext *TLS : AllThreadContexts)
393 Stats->add(TLS->StatsCumulative); 393 Stats->add(TLS->StatsCumulative);
394 } 394 }
395 } 395 }
396 396
397 // Translation thread startup routine. 397 /// Translation thread startup routine.
398 void translateFunctionsWrapper(ThreadContext *MyTLS) { 398 void translateFunctionsWrapper(ThreadContext *MyTLS) {
399 ICE_TLS_SET_FIELD(TLS, MyTLS); 399 ICE_TLS_SET_FIELD(TLS, MyTLS);
400 translateFunctions(); 400 translateFunctions();
401 } 401 }
402 // Translate functions from the Cfg queue until the queue is empty. 402 /// Translate functions from the Cfg queue until the queue is empty.
403 void translateFunctions(); 403 void translateFunctions();
404 404
405 // Emitter thread startup routine. 405 /// Emitter thread startup routine.
406 void emitterWrapper(ThreadContext *MyTLS) { 406 void emitterWrapper(ThreadContext *MyTLS) {
407 ICE_TLS_SET_FIELD(TLS, MyTLS); 407 ICE_TLS_SET_FIELD(TLS, MyTLS);
408 emitItems(); 408 emitItems();
409 } 409 }
410 // Emit functions and global initializers from the emitter queue 410 /// Emit functions and global initializers from the emitter queue
411 // until the queue is empty. 411 /// until the queue is empty.
412 void emitItems(); 412 void emitItems();
413 413
414 // Uses DataLowering to lower Globals. Side effects: 414 /// Uses DataLowering to lower Globals. Side effects:
415 // - discards the initializer list for the global variable in Globals. 415 /// - discards the initializer list for the global variable in Globals.
416 // - clears the Globals array. 416 /// - clears the Globals array.
417 void lowerGlobals(const IceString &SectionSuffix); 417 void lowerGlobals(const IceString &SectionSuffix);
418 418
419 // Lowers the profile information. 419 /// Lowers the profile information.
420 void lowerProfileData(); 420 void lowerProfileData();
421 421
422 // Utility function to match a symbol name against a match string. 422 /// Utility function to match a symbol name against a match string.
423 // This is used in a few cases where we want to take some action on 423 /// This is used in a few cases where we want to take some action on
424 // a particular function or symbol based on a command-line argument, 424 /// a particular function or symbol based on a command-line argument,
425 // such as changing the verbose level for a particular function. An 425 /// such as changing the verbose level for a particular function. An
426 // empty Match argument means match everything. Returns true if 426 /// empty Match argument means match everything. Returns true if
427 // there is a match. 427 /// there is a match.
428 static bool matchSymbolName(const IceString &SymbolName, 428 static bool matchSymbolName(const IceString &SymbolName,
429 const IceString &Match) { 429 const IceString &Match) {
430 return Match.empty() || Match == SymbolName; 430 return Match.empty() || Match == SymbolName;
431 } 431 }
432 432
433 // Return the randomization cookie for diversification. 433 /// Return the randomization cookie for diversification.
434 // Initialize the cookie if necessary 434 /// Initialize the cookie if necessary
435 uint32_t getRandomizationCookie() const { return RandomizationCookie; } 435 uint32_t getRandomizationCookie() const { return RandomizationCookie; }
436 436
437 private: 437 private:
438 // Try to ensure mutexes are allocated on separate cache lines. 438 // Try to ensure mutexes are allocated on separate cache lines.
439 439
440 // Destructors collaborate with Allocator 440 // Destructors collaborate with Allocator
441 ICE_CACHELINE_BOUNDARY; 441 ICE_CACHELINE_BOUNDARY;
442 // Managed by getAllocator() 442 // Managed by getAllocator()
443 GlobalLockType AllocLock; 443 GlobalLockType AllocLock;
444 ArenaAllocator<> Allocator; 444 ArenaAllocator<> Allocator;
(...skipping 18 matching lines...) Expand all
463 // Managed by getStatsCumulative() 463 // Managed by getStatsCumulative()
464 GlobalLockType StatsLock; 464 GlobalLockType StatsLock;
465 CodeStats StatsCumulative; 465 CodeStats StatsCumulative;
466 466
467 ICE_CACHELINE_BOUNDARY; 467 ICE_CACHELINE_BOUNDARY;
468 // Managed by getTimers() 468 // Managed by getTimers()
469 GlobalLockType TimerLock; 469 GlobalLockType TimerLock;
470 TimerList Timers; 470 TimerList Timers;
471 471
472 ICE_CACHELINE_BOUNDARY; 472 ICE_CACHELINE_BOUNDARY;
473 // StrLock is a global lock on the dump and emit output streams. 473 /// StrLock is a global lock on the dump and emit output streams.
474 typedef std::mutex StrLockType; 474 typedef std::mutex StrLockType;
475 StrLockType StrLock; 475 StrLockType StrLock;
476 Ostream *StrDump; // Stream for dumping / diagnostics 476 Ostream *StrDump; /// Stream for dumping / diagnostics
477 Ostream *StrEmit; // Stream for code emission 477 Ostream *StrEmit; /// Stream for code emission
478 Ostream *StrError; // Stream for logging errors. 478 Ostream *StrError; /// Stream for logging errors.
479 479
480 ICE_CACHELINE_BOUNDARY; 480 ICE_CACHELINE_BOUNDARY;
481 481
482 Intrinsics IntrinsicsInfo; 482 Intrinsics IntrinsicsInfo;
483 const ClFlags &Flags; 483 const ClFlags &Flags;
484 RandomNumberGenerator RNG; // TODO(stichnot): Move into Cfg. 484 RandomNumberGenerator RNG; // TODO(stichnot): Move into Cfg.
485 // TODO(jpp): move to EmitterContext. 485 // TODO(jpp): move to EmitterContext.
486 std::unique_ptr<ELFObjectWriter> ObjectWriter; 486 std::unique_ptr<ELFObjectWriter> ObjectWriter;
487 BoundedProducerConsumerQueue<Cfg> OptQ; 487 BoundedProducerConsumerQueue<Cfg> OptQ;
488 BoundedProducerConsumerQueue<EmitterWorkItem> EmitQ; 488 BoundedProducerConsumerQueue<EmitterWorkItem> EmitQ;
489 // DataLowering is only ever used by a single thread at a time (either in 489 // DataLowering is only ever used by a single thread at a time (either in
490 // emitItems(), or in IceCompiler::run before the compilation is over.) 490 // emitItems(), or in IceCompiler::run before the compilation is over.)
491 // TODO(jpp): move to EmitterContext. 491 // TODO(jpp): move to EmitterContext.
492 std::unique_ptr<TargetDataLowering> DataLowering; 492 std::unique_ptr<TargetDataLowering> DataLowering;
493 // If !HasEmittedCode, SubZero will accumulate all Globals (which are "true" 493 /// If !HasEmittedCode, SubZero will accumulate all Globals (which are "true"
494 // program global variables) until the first code WorkItem is seen. 494 /// program global variables) until the first code WorkItem is seen.
495 // TODO(jpp): move to EmitterContext. 495 // TODO(jpp): move to EmitterContext.
496 bool HasSeenCode = false; 496 bool HasSeenCode = false;
497 // TODO(jpp): move to EmitterContext. 497 // TODO(jpp): move to EmitterContext.
498 VariableDeclarationList Globals; 498 VariableDeclarationList Globals;
499 // TODO(jpp): move to EmitterContext. 499 // TODO(jpp): move to EmitterContext.
500 VariableDeclaration *ProfileBlockInfoVarDecl; 500 VariableDeclaration *ProfileBlockInfoVarDecl;
501 501
502 LockedPtr<ArenaAllocator<>> getAllocator() { 502 LockedPtr<ArenaAllocator<>> getAllocator() {
503 return LockedPtr<ArenaAllocator<>>(&Allocator, &AllocLock); 503 return LockedPtr<ArenaAllocator<>>(&Allocator, &AllocLock);
504 } 504 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
541 541
542 // Randomization Cookie 542 // Randomization Cookie
543 // Managed by getRandomizationCookie() 543 // Managed by getRandomizationCookie()
544 GlobalLockType RandomizationCookieLock; 544 GlobalLockType RandomizationCookieLock;
545 uint32_t RandomizationCookie = 0; 545 uint32_t RandomizationCookie = 0;
546 546
547 public: 547 public:
548 static void TlsInit() { ICE_TLS_INIT_FIELD(TLS); } 548 static void TlsInit() { ICE_TLS_INIT_FIELD(TLS); }
549 }; 549 };
550 550
551 // Helper class to push and pop a timer marker. The constructor 551 /// Helper class to push and pop a timer marker. The constructor
552 // pushes a marker, and the destructor pops it. This is for 552 /// pushes a marker, and the destructor pops it. This is for
553 // convenient timing of regions of code. 553 /// convenient timing of regions of code.
554 class TimerMarker { 554 class TimerMarker {
555 TimerMarker() = delete; 555 TimerMarker() = delete;
556 TimerMarker(const TimerMarker &) = delete; 556 TimerMarker(const TimerMarker &) = delete;
557 TimerMarker &operator=(const TimerMarker &) = delete; 557 TimerMarker &operator=(const TimerMarker &) = delete;
558 558
559 public: 559 public:
560 TimerMarker(TimerIdT ID, GlobalContext *Ctx, 560 TimerMarker(TimerIdT ID, GlobalContext *Ctx,
561 TimerStackIdT StackID = GlobalContext::TSK_Default) 561 TimerStackIdT StackID = GlobalContext::TSK_Default)
562 : ID(ID), Ctx(Ctx), StackID(StackID) { 562 : ID(ID), Ctx(Ctx), StackID(StackID) {
563 if (BuildDefs::dump()) 563 if (BuildDefs::dump())
(...skipping 14 matching lines...) Expand all
578 578
579 private: 579 private:
580 void push(); 580 void push();
581 void pushCfg(const Cfg *Func); 581 void pushCfg(const Cfg *Func);
582 const TimerIdT ID; 582 const TimerIdT ID;
583 GlobalContext *Ctx; 583 GlobalContext *Ctx;
584 const TimerStackIdT StackID; 584 const TimerStackIdT StackID;
585 bool Active = false; 585 bool Active = false;
586 }; 586 };
587 587
588 // Helper class for locking the streams and then automatically 588 /// Helper class for locking the streams and then automatically
589 // unlocking them. 589 /// unlocking them.
590 class OstreamLocker { 590 class OstreamLocker {
591 private: 591 private:
592 OstreamLocker() = delete; 592 OstreamLocker() = delete;
593 OstreamLocker(const OstreamLocker &) = delete; 593 OstreamLocker(const OstreamLocker &) = delete;
594 OstreamLocker &operator=(const OstreamLocker &) = delete; 594 OstreamLocker &operator=(const OstreamLocker &) = delete;
595 595
596 public: 596 public:
597 explicit OstreamLocker(GlobalContext *Ctx) : Ctx(Ctx) { Ctx->lockStr(); } 597 explicit OstreamLocker(GlobalContext *Ctx) : Ctx(Ctx) { Ctx->lockStr(); }
598 ~OstreamLocker() { Ctx->unlockStr(); } 598 ~OstreamLocker() { Ctx->unlockStr(); }
599 599
600 private: 600 private:
601 GlobalContext *const Ctx; 601 GlobalContext *const Ctx;
602 }; 602 };
603 603
604 } // end of namespace Ice 604 } // end of namespace Ice
605 605
606 #endif // SUBZERO_SRC_ICEGLOBALCONTEXT_H 606 #endif // SUBZERO_SRC_ICEGLOBALCONTEXT_H
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698