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

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 raised in last CL. 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
« no previous file with comments | « src/IceGlobalContext.h ('k') | src/IceTranslator.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.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 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
206 TypePool<IceType_i8, int8_t, ConstantInteger32> Integers8; 206 TypePool<IceType_i8, int8_t, ConstantInteger32> Integers8;
207 TypePool<IceType_i16, int16_t, ConstantInteger32> Integers16; 207 TypePool<IceType_i16, int16_t, ConstantInteger32> Integers16;
208 TypePool<IceType_i32, int32_t, ConstantInteger32> Integers32; 208 TypePool<IceType_i32, int32_t, ConstantInteger32> Integers32;
209 TypePool<IceType_i64, int64_t, ConstantInteger64> Integers64; 209 TypePool<IceType_i64, int64_t, ConstantInteger64> Integers64;
210 TypePool<IceType_i32, RelocatableTuple, ConstantRelocatable> Relocatables; 210 TypePool<IceType_i32, RelocatableTuple, ConstantRelocatable> Relocatables;
211 TypePool<IceType_i32, RelocatableTuple, ConstantRelocatable> 211 TypePool<IceType_i32, RelocatableTuple, ConstantRelocatable>
212 ExternRelocatables; 212 ExternRelocatables;
213 UndefPool Undefs; 213 UndefPool Undefs;
214 }; 214 };
215 215
216 void GlobalContext::waitForWorkerThreads() {
217 if (WaitForWorkerThreadsCalled.exchange(true))
218 return;
219 optQueueNotifyEnd();
220 for (std::thread &Worker : TranslationThreads) {
221 Worker.join();
222 }
223 TranslationThreads.clear();
224
225 // Only notify the emit queue to end after all the translation threads have
226 // ended.
227 emitQueueNotifyEnd();
228 for (std::thread &Worker : EmitterThreads) {
229 Worker.join();
230 }
231 EmitterThreads.clear();
232
233 if (BuildDefs::timers()) {
234 auto Timers = getTimers();
235 for (ThreadContext *TLS : AllThreadContexts)
236 Timers->mergeFrom(TLS->Timers);
237 }
238 if (BuildDefs::dump()) {
239 // Do a separate loop over AllThreadContexts to avoid holding two locks at
240 // once.
241 auto Stats = getStatsCumulative();
242 for (ThreadContext *TLS : AllThreadContexts)
243 Stats->add(TLS->StatsCumulative);
244 }
245 }
246
216 void GlobalContext::CodeStats::dump(const std::string &Name, 247 void GlobalContext::CodeStats::dump(const std::string &Name,
217 GlobalContext *Ctx) { 248 GlobalContext *Ctx) {
218 if (!BuildDefs::dump()) 249 if (!BuildDefs::dump())
219 return; 250 return;
220 OstreamLocker _(Ctx); 251 OstreamLocker _(Ctx);
221 Ostream &Str = Ctx->getStrDump(); 252 Ostream &Str = Ctx->getStrDump();
222 #define X(str, tag) \ 253 #define X(str, tag) \
223 Str << "|" << Name << "|" str "|" << Stats[CS_##tag] << "\n"; 254 Str << "|" << Name << "|" str "|" << Stats[CS_##tag] << "\n";
224 CODESTATS_TABLE 255 CODESTATS_TABLE
225 #undef X 256 #undef X
(...skipping 19 matching lines...) Expand all
245 Str << "|ExtRel=" << Pool->ExternRelocatables.size(); 276 Str << "|ExtRel=" << Pool->ExternRelocatables.size();
246 } 277 }
247 Str << "\n"; 278 Str << "\n";
248 } 279 }
249 280
250 GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError, 281 GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, Ostream *OsError,
251 ELFStreamer *ELFStr) 282 ELFStreamer *ELFStr)
252 : Strings(new StringPool()), ConstPool(new ConstantPool()), ErrorStatus(), 283 : Strings(new StringPool()), ConstPool(new ConstantPool()), ErrorStatus(),
253 StrDump(OsDump), StrEmit(OsEmit), StrError(OsError), IntrinsicsInfo(this), 284 StrDump(OsDump), StrEmit(OsEmit), StrError(OsError), IntrinsicsInfo(this),
254 ObjectWriter(), OptQ(/*Sequential=*/Flags.isSequential(), 285 ObjectWriter(), OptQ(/*Sequential=*/Flags.isSequential(),
255 /*MaxSize=*/Flags.getNumTranslationThreads()), 286 /*MaxSize=*/
287 (Flags.getParseParallel() && Flags.getBuildOnRead())
288 ? MaxOptQSize
289 : Flags.getNumTranslationThreads()),
256 // EmitQ is allowed unlimited size. 290 // EmitQ is allowed unlimited size.
257 EmitQ(/*Sequential=*/Flags.isSequential()), 291 EmitQ(/*Sequential=*/Flags.isSequential()),
258 DataLowering(TargetDataLowering::createLowering(this)) { 292 DataLowering(TargetDataLowering::createLowering(this)) {
259 assert(OsDump && "OsDump is not defined for GlobalContext"); 293 assert(OsDump && "OsDump is not defined for GlobalContext");
260 assert(OsEmit && "OsEmit is not defined for GlobalContext"); 294 assert(OsEmit && "OsEmit is not defined for GlobalContext");
261 assert(OsError && "OsError is not defined for GlobalContext"); 295 assert(OsError && "OsError is not defined for GlobalContext");
262 // Make sure thread_local fields are properly initialized before any 296 // Make sure thread_local fields are properly initialized before any
263 // accesses are made. Do this here instead of at the start of 297 // accesses are made. Do this here instead of at the start of
264 // main() so that all clients (e.g. unit tests) can benefit for 298 // main() so that all clients (e.g. unit tests) can benefit for
265 // free. 299 // free.
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 RuntimeHelperFunc[static_cast<size_t>(RuntimeHelper::H_##Tag)] = \ 332 RuntimeHelperFunc[static_cast<size_t>(RuntimeHelper::H_##Tag)] = \
299 getConstantExternSym(getGlobalString(Name)); 333 getConstantExternSym(getGlobalString(Name));
300 RUNTIME_HELPER_FUNCTIONS_TABLE 334 RUNTIME_HELPER_FUNCTIONS_TABLE
301 #undef X 335 #undef X
302 336
303 TargetLowering::staticInit(this); 337 TargetLowering::staticInit(this);
304 } 338 }
305 339
306 void GlobalContext::translateFunctions() { 340 void GlobalContext::translateFunctions() {
307 TimerMarker Timer(TimerStack::TT_translateFunctions, this); 341 TimerMarker Timer(TimerStack::TT_translateFunctions, this);
308 while (std::unique_ptr<Cfg> Func = optQueueBlockingPop()) { 342 while (std::unique_ptr<OptWorkItem> OptItem = optQueueBlockingPop()) {
343 auto Func = OptItem->getParsedCfg();
309 // Install Func in TLS for Cfg-specific container allocators. 344 // Install Func in TLS for Cfg-specific container allocators.
310 CfgLocalAllocatorScope _(Func.get()); 345 CfgLocalAllocatorScope _(Func.get());
311 // Reset per-function stats being accumulated in TLS. 346 // Reset per-function stats being accumulated in TLS.
312 resetStats(); 347 resetStats();
313 // Set verbose level to none if the current function does NOT 348 // Set verbose level to none if the current function does NOT
314 // match the -verbose-focus command-line option. 349 // match the -verbose-focus command-line option.
315 if (!matchSymbolName(Func->getFunctionName(), 350 if (!matchSymbolName(Func->getFunctionName(),
316 getFlags().getVerboseFocusOn())) 351 getFlags().getVerboseFocusOn()))
317 Func->setVerbose(IceV_None); 352 Func->setVerbose(IceV_None);
318 // Disable translation if -notranslate is specified, or if the 353 // Disable translation if -notranslate is specified, or if the
(...skipping 552 matching lines...) Expand 10 before | Expand all | Expand 10 after
871 const std::string &NewName) { 906 const std::string &NewName) {
872 auto Timers = &ICE_TLS_GET_FIELD(TLS)->Timers; 907 auto Timers = &ICE_TLS_GET_FIELD(TLS)->Timers;
873 assert(StackID < Timers->size()); 908 assert(StackID < Timers->size());
874 Timers->at(StackID).setName(NewName); 909 Timers->at(StackID).setName(NewName);
875 } 910 }
876 911
877 // Note: optQueueBlockingPush and optQueueBlockingPop use unique_ptr at the 912 // Note: optQueueBlockingPush and optQueueBlockingPop use unique_ptr at the
878 // interface to take and transfer ownership, but they internally store the raw 913 // interface to take and transfer ownership, but they internally store the raw
879 // Cfg pointer in the work queue. This allows e.g. future queue optimizations 914 // Cfg pointer in the work queue. This allows e.g. future queue optimizations
880 // such as the use of atomics to modify queue elements. 915 // such as the use of atomics to modify queue elements.
881 void GlobalContext::optQueueBlockingPush(std::unique_ptr<Cfg> Func) { 916 void GlobalContext::optQueueBlockingPush(std::unique_ptr<OptWorkItem> Item) {
882 assert(Func); 917 assert(Item);
883 { 918 {
884 TimerMarker _(TimerStack::TT_qTransPush, this); 919 TimerMarker _(TimerStack::TT_qTransPush, this);
885 OptQ.blockingPush(std::move(Func)); 920 OptQ.blockingPush(std::move(Item));
886 } 921 }
887 if (getFlags().isSequential()) 922 if (getFlags().isSequential())
888 translateFunctions(); 923 translateFunctions();
889 } 924 }
890 925
891 std::unique_ptr<Cfg> GlobalContext::optQueueBlockingPop() { 926 std::unique_ptr<OptWorkItem> GlobalContext::optQueueBlockingPop() {
892 TimerMarker _(TimerStack::TT_qTransPop, this); 927 TimerMarker _(TimerStack::TT_qTransPop, this);
893 return std::unique_ptr<Cfg>(OptQ.blockingPop()); 928 return std::unique_ptr<OptWorkItem>(OptQ.blockingPop());
894 } 929 }
895 930
896 void GlobalContext::emitQueueBlockingPush( 931 void GlobalContext::emitQueueBlockingPush(
897 std::unique_ptr<EmitterWorkItem> Item) { 932 std::unique_ptr<EmitterWorkItem> Item) {
898 assert(Item); 933 assert(Item);
899 { 934 {
900 TimerMarker _(TimerStack::TT_qEmitPush, this); 935 TimerMarker _(TimerStack::TT_qEmitPush, this);
901 EmitQ.blockingPush(std::move(Item)); 936 EmitQ.blockingPush(std::move(Item));
902 } 937 }
903 if (getFlags().isSequential()) 938 if (getFlags().isSequential())
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
963 Ctx = Func->getContext(); 998 Ctx = Func->getContext();
964 Active = 999 Active =
965 Func->getFocusedTiming() || Ctx->getFlags().getSubzeroTimingEnabled(); 1000 Func->getFocusedTiming() || Ctx->getFlags().getSubzeroTimingEnabled();
966 if (Active) 1001 if (Active)
967 Ctx->pushTimer(ID, StackID); 1002 Ctx->pushTimer(ID, StackID);
968 } 1003 }
969 1004
970 ICE_TLS_DEFINE_FIELD(GlobalContext::ThreadContext *, GlobalContext, TLS); 1005 ICE_TLS_DEFINE_FIELD(GlobalContext::ThreadContext *, GlobalContext, TLS);
971 1006
972 } // end of namespace Ice 1007 } // end of namespace Ice
OLDNEW
« no previous file with comments | « src/IceGlobalContext.h ('k') | src/IceTranslator.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698