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

Side by Side Diff: src/IceGlobalContext.cpp

Issue 1834473002: Allow Subzero to parse function blocks in parallel. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Fix issues from last patch. Created 4 years, 9 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.cpp - Global context defs -------------===// 1 //===- subzero/src/IceGlobalContext.cpp - Global context defs -------------===//
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 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 TypePool<IceType_i8, int8_t, ConstantInteger32> Integers8; 211 TypePool<IceType_i8, int8_t, ConstantInteger32> Integers8;
212 TypePool<IceType_i16, int16_t, ConstantInteger32> Integers16; 212 TypePool<IceType_i16, int16_t, ConstantInteger32> Integers16;
213 TypePool<IceType_i32, int32_t, ConstantInteger32> Integers32; 213 TypePool<IceType_i32, int32_t, ConstantInteger32> Integers32;
214 TypePool<IceType_i64, int64_t, ConstantInteger64> Integers64; 214 TypePool<IceType_i64, int64_t, ConstantInteger64> Integers64;
215 TypePool<IceType_i32, RelocatableTuple, ConstantRelocatable> Relocatables; 215 TypePool<IceType_i32, RelocatableTuple, ConstantRelocatable> Relocatables;
216 TypePool<IceType_i32, RelocatableTuple, ConstantRelocatable> 216 TypePool<IceType_i32, RelocatableTuple, ConstantRelocatable>
217 ExternRelocatables; 217 ExternRelocatables;
218 UndefPool Undefs; 218 UndefPool Undefs;
219 }; 219 };
220 220
221 void GlobalContext::waitForWorkerThreads() {
222 { // Make sure we wait at most once.
223 std::unique_lock<GlobalLockType> L(WaitForWorkersLock);
Jim Stichnoth 2016/03/25 04:31:04 Our new super-awesome coding style would name this
Karl 2016/03/29 17:35:02 Removed, went with atomic_bool.
224 if (WaitForWorkerThreadsCalled)
Jim Stichnoth 2016/03/25 04:31:04 It seems that WaitForWorkerThreadsCalled could act
Karl 2016/03/29 17:35:02 Changed to atomic_bool.
225 return;
226 WaitForWorkerThreadsCalled = true;
227 }
228 optQueueNotifyEnd();
229 for (std::thread &Worker : TranslationThreads) {
230 Worker.join();
231 }
232 TranslationThreads.clear();
233
234 // Only notify the emit queue to end after all the translation threads have
235 // ended.
236 emitQueueNotifyEnd();
237 for (std::thread &Worker : EmitterThreads) {
238 Worker.join();
239 }
240 EmitterThreads.clear();
241
242 if (BuildDefs::timers()) {
243 auto Timers = getTimers();
244 for (ThreadContext *TLS : AllThreadContexts)
245 Timers->mergeFrom(TLS->Timers);
246 }
247 if (BuildDefs::dump()) {
248 // Do a separate loop over AllThreadContexts to avoid holding two locks
249 // at once.
250 auto Stats = getStatsCumulative();
251 for (ThreadContext *TLS : AllThreadContexts)
252 Stats->add(TLS->StatsCumulative);
253 }
254 }
255
221 void GlobalContext::CodeStats::dump(const IceString &Name, GlobalContext *Ctx) { 256 void GlobalContext::CodeStats::dump(const IceString &Name, GlobalContext *Ctx) {
222 if (!BuildDefs::dump()) 257 if (!BuildDefs::dump())
223 return; 258 return;
224 OstreamLocker _(Ctx); 259 OstreamLocker _(Ctx);
225 Ostream &Str = Ctx->getStrDump(); 260 Ostream &Str = Ctx->getStrDump();
226 #define X(str, tag) \ 261 #define X(str, tag) \
227 Str << "|" << Name << "|" str "|" << Stats[CS_##tag] << "\n"; 262 Str << "|" << Name << "|" str "|" << Stats[CS_##tag] << "\n";
228 CODESTATS_TABLE 263 CODESTATS_TABLE
229 #undef X 264 #undef X
230 Str << "|" << Name << "|Spills+Fills|" 265 Str << "|" << Name << "|Spills+Fills|"
(...skipping 18 matching lines...) Expand all
249 Str << "|ExtRel=" << Pool->ExternRelocatables.size(); 284 Str << "|ExtRel=" << Pool->ExternRelocatables.size();
250 } 285 }
251 Str << "\n"; 286 Str << "\n";
252 } 287 }
253 288
254 GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError, 289 GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError,
255 ELFStreamer *ELFStr) 290 ELFStreamer *ELFStr)
256 : ConstPool(new ConstantPool()), ErrorStatus(), StrDump(OsDump), 291 : ConstPool(new ConstantPool()), ErrorStatus(), StrDump(OsDump),
257 StrEmit(OsEmit), StrError(OsError), ObjectWriter(), 292 StrEmit(OsEmit), StrError(OsError), ObjectWriter(),
258 OptQ(/*Sequential=*/Flags.isSequential(), 293 OptQ(/*Sequential=*/Flags.isSequential(),
259 /*MaxSize=*/Flags.getNumTranslationThreads()), 294 /*MaxSize=*/
295 (Flags.getParseParallel() && Flags.getBuildOnRead())
296 ? MaxOptQSize
297 : Flags.getNumTranslationThreads()),
260 // EmitQ is allowed unlimited size. 298 // EmitQ is allowed unlimited size.
261 EmitQ(/*Sequential=*/Flags.isSequential()), 299 EmitQ(/*Sequential=*/Flags.isSequential()),
262 DataLowering(TargetDataLowering::createLowering(this)) { 300 DataLowering(TargetDataLowering::createLowering(this)) {
263 assert(OsDump && "OsDump is not defined for GlobalContext"); 301 assert(OsDump && "OsDump is not defined for GlobalContext");
264 assert(OsEmit && "OsEmit is not defined for GlobalContext"); 302 assert(OsEmit && "OsEmit is not defined for GlobalContext");
265 assert(OsError && "OsError is not defined for GlobalContext"); 303 assert(OsError && "OsError is not defined for GlobalContext");
266 // Make sure thread_local fields are properly initialized before any 304 // Make sure thread_local fields are properly initialized before any
267 // accesses are made. Do this here instead of at the start of 305 // accesses are made. Do this here instead of at the start of
268 // main() so that all clients (e.g. unit tests) can benefit for 306 // main() so that all clients (e.g. unit tests) can benefit for
269 // free. 307 // free.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 RuntimeHelperFunc[static_cast<size_t>(RuntimeHelper::H_##Tag)] = \ 340 RuntimeHelperFunc[static_cast<size_t>(RuntimeHelper::H_##Tag)] = \
303 getConstantExternSym(Name); 341 getConstantExternSym(Name);
304 RUNTIME_HELPER_FUNCTIONS_TABLE 342 RUNTIME_HELPER_FUNCTIONS_TABLE
305 #undef X 343 #undef X
306 344
307 TargetLowering::staticInit(this); 345 TargetLowering::staticInit(this);
308 } 346 }
309 347
310 void GlobalContext::translateFunctions() { 348 void GlobalContext::translateFunctions() {
311 TimerMarker Timer(TimerStack::TT_translateFunctions, this); 349 TimerMarker Timer(TimerStack::TT_translateFunctions, this);
312 while (std::unique_ptr<Cfg> Func = optQueueBlockingPop()) { 350 while (std::unique_ptr<OptWorkItem> OptItem = optQueueBlockingPop()) {
351 std::unique_ptr<Cfg> Func = OptItem->getParsedCfg();
313 // Install Func in TLS for Cfg-specific container allocators. 352 // Install Func in TLS for Cfg-specific container allocators.
314 CfgLocalAllocatorScope _(Func.get()); 353 CfgLocalAllocatorScope _(Func.get());
315 // Reset per-function stats being accumulated in TLS. 354 // Reset per-function stats being accumulated in TLS.
316 resetStats(); 355 resetStats();
317 // Set verbose level to none if the current function does NOT 356 // Set verbose level to none if the current function does NOT
318 // match the -verbose-focus command-line option. 357 // match the -verbose-focus command-line option.
319 if (!matchSymbolName(Func->getFunctionName(), 358 if (!matchSymbolName(Func->getFunctionName(),
320 getFlags().getVerboseFocusOn())) 359 getFlags().getVerboseFocusOn()))
321 Func->setVerbose(IceV_None); 360 Func->setVerbose(IceV_None);
322 // Disable translation if -notranslate is specified, or if the 361 // Disable translation if -notranslate is specified, or if the
(...skipping 537 matching lines...) Expand 10 before | Expand all | Expand 10 after
860 const IceString &NewName) { 899 const IceString &NewName) {
861 auto Timers = &ICE_TLS_GET_FIELD(TLS)->Timers; 900 auto Timers = &ICE_TLS_GET_FIELD(TLS)->Timers;
862 assert(StackID < Timers->size()); 901 assert(StackID < Timers->size());
863 Timers->at(StackID).setName(NewName); 902 Timers->at(StackID).setName(NewName);
864 } 903 }
865 904
866 // Note: optQueueBlockingPush and optQueueBlockingPop use unique_ptr at the 905 // Note: optQueueBlockingPush and optQueueBlockingPop use unique_ptr at the
867 // interface to take and transfer ownership, but they internally store the raw 906 // interface to take and transfer ownership, but they internally store the raw
868 // Cfg pointer in the work queue. This allows e.g. future queue optimizations 907 // Cfg pointer in the work queue. This allows e.g. future queue optimizations
869 // such as the use of atomics to modify queue elements. 908 // such as the use of atomics to modify queue elements.
870 void GlobalContext::optQueueBlockingPush(std::unique_ptr<Cfg> Func) { 909 void GlobalContext::optQueueBlockingPush(std::unique_ptr<OptWorkItem> Item) {
871 assert(Func); 910 assert(Item);
872 { 911 {
873 TimerMarker _(TimerStack::TT_qTransPush, this); 912 TimerMarker _(TimerStack::TT_qTransPush, this);
874 OptQ.blockingPush(std::move(Func)); 913 OptQ.blockingPush(std::move(Item));
875 } 914 }
876 if (getFlags().isSequential()) 915 if (getFlags().isSequential())
877 translateFunctions(); 916 translateFunctions();
878 } 917 }
879 918
880 std::unique_ptr<Cfg> GlobalContext::optQueueBlockingPop() { 919 std::unique_ptr<OptWorkItem> GlobalContext::optQueueBlockingPop() {
881 TimerMarker _(TimerStack::TT_qTransPop, this); 920 TimerMarker _(TimerStack::TT_qTransPop, this);
882 return std::unique_ptr<Cfg>(OptQ.blockingPop()); 921 return std::unique_ptr<OptWorkItem>(OptQ.blockingPop());
883 } 922 }
884 923
885 void GlobalContext::emitQueueBlockingPush( 924 void GlobalContext::emitQueueBlockingPush(
886 std::unique_ptr<EmitterWorkItem> Item) { 925 std::unique_ptr<EmitterWorkItem> Item) {
887 assert(Item); 926 assert(Item);
888 { 927 {
889 TimerMarker _(TimerStack::TT_qEmitPush, this); 928 TimerMarker _(TimerStack::TT_qEmitPush, this);
890 EmitQ.blockingPush(std::move(Item)); 929 EmitQ.blockingPush(std::move(Item));
891 } 930 }
892 if (getFlags().isSequential()) 931 if (getFlags().isSequential())
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
947 Ctx = Func->getContext(); 986 Ctx = Func->getContext();
948 Active = 987 Active =
949 Func->getFocusedTiming() || Ctx->getFlags().getSubzeroTimingEnabled(); 988 Func->getFocusedTiming() || Ctx->getFlags().getSubzeroTimingEnabled();
950 if (Active) 989 if (Active)
951 Ctx->pushTimer(ID, StackID); 990 Ctx->pushTimer(ID, StackID);
952 } 991 }
953 992
954 ICE_TLS_DEFINE_FIELD(GlobalContext::ThreadContext *, GlobalContext, TLS); 993 ICE_TLS_DEFINE_FIELD(GlobalContext::ThreadContext *, GlobalContext, TLS);
955 994
956 } // end of namespace Ice 995 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698