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

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 nits. Created 4 years, 8 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 if (WaitForWorkerThreadsCalled.exchange(true))
223 return;
224 optQueueNotifyEnd();
225 for (std::thread &Worker : TranslationThreads) {
226 Worker.join();
227 }
228 TranslationThreads.clear();
229
230 // Only notify the emit queue to end after all the translation threads have
231 // ended.
232 emitQueueNotifyEnd();
233 for (std::thread &Worker : EmitterThreads) {
234 Worker.join();
235 }
236 EmitterThreads.clear();
237
238 if (BuildDefs::timers()) {
239 auto Timers = getTimers();
240 for (ThreadContext *TLS : AllThreadContexts)
241 Timers->mergeFrom(TLS->Timers);
242 }
243 if (BuildDefs::dump()) {
244 // Do a separate loop over AllThreadContexts to avoid holding two locks
Jim Stichnoth 2016/03/31 16:08:08 reflow...
Karl 2016/03/31 16:33:49 Done.
245 // at once.
246 auto Stats = getStatsCumulative();
247 for (ThreadContext *TLS : AllThreadContexts)
248 Stats->add(TLS->StatsCumulative);
249 }
250 }
251
221 void GlobalContext::CodeStats::dump(const IceString &Name, GlobalContext *Ctx) { 252 void GlobalContext::CodeStats::dump(const IceString &Name, GlobalContext *Ctx) {
222 if (!BuildDefs::dump()) 253 if (!BuildDefs::dump())
223 return; 254 return;
224 OstreamLocker _(Ctx); 255 OstreamLocker _(Ctx);
225 Ostream &Str = Ctx->getStrDump(); 256 Ostream &Str = Ctx->getStrDump();
226 #define X(str, tag) \ 257 #define X(str, tag) \
227 Str << "|" << Name << "|" str "|" << Stats[CS_##tag] << "\n"; 258 Str << "|" << Name << "|" str "|" << Stats[CS_##tag] << "\n";
228 CODESTATS_TABLE 259 CODESTATS_TABLE
229 #undef X 260 #undef X
230 Str << "|" << Name << "|Spills+Fills|" 261 Str << "|" << Name << "|Spills+Fills|"
(...skipping 16 matching lines...) Expand all
247 Str << "|i64=" << Pool->Integers64.size(); 278 Str << "|i64=" << Pool->Integers64.size();
248 Str << "|Rel=" << Pool->Relocatables.size(); 279 Str << "|Rel=" << Pool->Relocatables.size();
249 Str << "|ExtRel=" << Pool->ExternRelocatables.size(); 280 Str << "|ExtRel=" << Pool->ExternRelocatables.size();
250 } 281 }
251 Str << "\n"; 282 Str << "\n";
252 } 283 }
253 284
254 GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError, 285 GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError,
255 ELFStreamer *ELFStr) 286 ELFStreamer *ELFStr)
256 : ConstPool(new ConstantPool()), ErrorStatus(), StrDump(OsDump), 287 : ConstPool(new ConstantPool()), ErrorStatus(), StrDump(OsDump),
257 StrEmit(OsEmit), StrError(OsError), ObjectWriter(), 288 StrEmit(OsEmit), StrError(OsError), WaitForWorkerThreadsCalled(false),
258 OptQ(/*Sequential=*/Flags.isSequential(), 289 ObjectWriter(), OptQ(/*Sequential=*/Flags.isSequential(),
259 /*MaxSize=*/Flags.getNumTranslationThreads()), 290 /*MaxSize=*/
291 (Flags.getParseParallel() && Flags.getBuildOnRead())
292 ? MaxOptQSize
293 : Flags.getNumTranslationThreads()),
260 // EmitQ is allowed unlimited size. 294 // EmitQ is allowed unlimited size.
261 EmitQ(/*Sequential=*/Flags.isSequential()), 295 EmitQ(/*Sequential=*/Flags.isSequential()),
262 DataLowering(TargetDataLowering::createLowering(this)) { 296 DataLowering(TargetDataLowering::createLowering(this)) {
263 assert(OsDump && "OsDump is not defined for GlobalContext"); 297 assert(OsDump && "OsDump is not defined for GlobalContext");
264 assert(OsEmit && "OsEmit is not defined for GlobalContext"); 298 assert(OsEmit && "OsEmit is not defined for GlobalContext");
265 assert(OsError && "OsError is not defined for GlobalContext"); 299 assert(OsError && "OsError is not defined for GlobalContext");
266 // Make sure thread_local fields are properly initialized before any 300 // Make sure thread_local fields are properly initialized before any
267 // accesses are made. Do this here instead of at the start of 301 // 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 302 // main() so that all clients (e.g. unit tests) can benefit for
269 // free. 303 // free.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
302 RuntimeHelperFunc[static_cast<size_t>(RuntimeHelper::H_##Tag)] = \ 336 RuntimeHelperFunc[static_cast<size_t>(RuntimeHelper::H_##Tag)] = \
303 getConstantExternSym(Name); 337 getConstantExternSym(Name);
304 RUNTIME_HELPER_FUNCTIONS_TABLE 338 RUNTIME_HELPER_FUNCTIONS_TABLE
305 #undef X 339 #undef X
306 340
307 TargetLowering::staticInit(this); 341 TargetLowering::staticInit(this);
308 } 342 }
309 343
310 void GlobalContext::translateFunctions() { 344 void GlobalContext::translateFunctions() {
311 TimerMarker Timer(TimerStack::TT_translateFunctions, this); 345 TimerMarker Timer(TimerStack::TT_translateFunctions, this);
312 while (std::unique_ptr<Cfg> Func = optQueueBlockingPop()) { 346 while (std::unique_ptr<OptWorkItem> OptItem = optQueueBlockingPop()) {
347 std::unique_ptr<Cfg> Func = OptItem->getParsedCfg();
John 2016/03/31 15:51:36 optional: auto
Karl 2016/03/31 16:33:49 Done.
313 // Install Func in TLS for Cfg-specific container allocators. 348 // Install Func in TLS for Cfg-specific container allocators.
314 CfgLocalAllocatorScope _(Func.get()); 349 CfgLocalAllocatorScope _(Func.get());
315 // Reset per-function stats being accumulated in TLS. 350 // Reset per-function stats being accumulated in TLS.
316 resetStats(); 351 resetStats();
317 // Set verbose level to none if the current function does NOT 352 // Set verbose level to none if the current function does NOT
318 // match the -verbose-focus command-line option. 353 // match the -verbose-focus command-line option.
319 if (!matchSymbolName(Func->getFunctionName(), 354 if (!matchSymbolName(Func->getFunctionName(),
320 getFlags().getVerboseFocusOn())) 355 getFlags().getVerboseFocusOn()))
321 Func->setVerbose(IceV_None); 356 Func->setVerbose(IceV_None);
322 // Disable translation if -notranslate is specified, or if the 357 // 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) { 895 const IceString &NewName) {
861 auto Timers = &ICE_TLS_GET_FIELD(TLS)->Timers; 896 auto Timers = &ICE_TLS_GET_FIELD(TLS)->Timers;
862 assert(StackID < Timers->size()); 897 assert(StackID < Timers->size());
863 Timers->at(StackID).setName(NewName); 898 Timers->at(StackID).setName(NewName);
864 } 899 }
865 900
866 // Note: optQueueBlockingPush and optQueueBlockingPop use unique_ptr at the 901 // Note: optQueueBlockingPush and optQueueBlockingPop use unique_ptr at the
867 // interface to take and transfer ownership, but they internally store the raw 902 // 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 903 // Cfg pointer in the work queue. This allows e.g. future queue optimizations
869 // such as the use of atomics to modify queue elements. 904 // such as the use of atomics to modify queue elements.
870 void GlobalContext::optQueueBlockingPush(std::unique_ptr<Cfg> Func) { 905 void GlobalContext::optQueueBlockingPush(std::unique_ptr<OptWorkItem> Item) {
871 assert(Func); 906 assert(Item);
872 { 907 {
873 TimerMarker _(TimerStack::TT_qTransPush, this); 908 TimerMarker _(TimerStack::TT_qTransPush, this);
874 OptQ.blockingPush(std::move(Func)); 909 OptQ.blockingPush(std::move(Item));
875 } 910 }
876 if (getFlags().isSequential()) 911 if (getFlags().isSequential())
877 translateFunctions(); 912 translateFunctions();
878 } 913 }
879 914
880 std::unique_ptr<Cfg> GlobalContext::optQueueBlockingPop() { 915 std::unique_ptr<OptWorkItem> GlobalContext::optQueueBlockingPop() {
881 TimerMarker _(TimerStack::TT_qTransPop, this); 916 TimerMarker _(TimerStack::TT_qTransPop, this);
882 return std::unique_ptr<Cfg>(OptQ.blockingPop()); 917 return std::unique_ptr<OptWorkItem>(OptQ.blockingPop());
883 } 918 }
884 919
885 void GlobalContext::emitQueueBlockingPush( 920 void GlobalContext::emitQueueBlockingPush(
886 std::unique_ptr<EmitterWorkItem> Item) { 921 std::unique_ptr<EmitterWorkItem> Item) {
887 assert(Item); 922 assert(Item);
888 { 923 {
889 TimerMarker _(TimerStack::TT_qEmitPush, this); 924 TimerMarker _(TimerStack::TT_qEmitPush, this);
890 EmitQ.blockingPush(std::move(Item)); 925 EmitQ.blockingPush(std::move(Item));
891 } 926 }
892 if (getFlags().isSequential()) 927 if (getFlags().isSequential())
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
947 Ctx = Func->getContext(); 982 Ctx = Func->getContext();
948 Active = 983 Active =
949 Func->getFocusedTiming() || Ctx->getFlags().getSubzeroTimingEnabled(); 984 Func->getFocusedTiming() || Ctx->getFlags().getSubzeroTimingEnabled();
950 if (Active) 985 if (Active)
951 Ctx->pushTimer(ID, StackID); 986 Ctx->pushTimer(ID, StackID);
952 } 987 }
953 988
954 ICE_TLS_DEFINE_FIELD(GlobalContext::ThreadContext *, GlobalContext, TLS); 989 ICE_TLS_DEFINE_FIELD(GlobalContext::ThreadContext *, GlobalContext, TLS);
955 990
956 } // end of namespace Ice 991 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceGlobalContext.h ('k') | src/IceTranslator.cpp » ('j') | src/PNaClTranslator.cpp » ('J')

Powered by Google App Engine
This is Rietveld 408576698