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

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

Powered by Google App Engine
This is Rietveld 408576698