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

Side by Side Diff: src/IceGlobalContext.cpp

Issue 848193003: Subzero: Add locking to prepare for multithreaded translation. (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Document the OstreamLocker class Created 5 years, 11 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 // This file defines aspects of the compilation that persist across 10 // This file defines aspects of the compilation that persist across
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 TypePool<IceType_f64, double, ConstantDouble> Doubles; 101 TypePool<IceType_f64, double, ConstantDouble> Doubles;
102 TypePool<IceType_i1, int8_t, ConstantInteger32> Integers1; 102 TypePool<IceType_i1, int8_t, ConstantInteger32> Integers1;
103 TypePool<IceType_i8, int8_t, ConstantInteger32> Integers8; 103 TypePool<IceType_i8, int8_t, ConstantInteger32> Integers8;
104 TypePool<IceType_i16, int16_t, ConstantInteger32> Integers16; 104 TypePool<IceType_i16, int16_t, ConstantInteger32> Integers16;
105 TypePool<IceType_i32, int32_t, ConstantInteger32> Integers32; 105 TypePool<IceType_i32, int32_t, ConstantInteger32> Integers32;
106 TypePool<IceType_i64, int64_t, ConstantInteger64> Integers64; 106 TypePool<IceType_i64, int64_t, ConstantInteger64> Integers64;
107 TypePool<IceType_i32, RelocatableTuple, ConstantRelocatable> Relocatables; 107 TypePool<IceType_i32, RelocatableTuple, ConstantRelocatable> Relocatables;
108 UndefPool Undefs; 108 UndefPool Undefs;
109 }; 109 };
110 110
111 void CodeStats::dump(const IceString &Name, Ostream &Str) { 111 void GlobalContext::CodeStats::dump(const IceString &Name, Ostream &Str) {
112 if (!ALLOW_DUMP) 112 if (!ALLOW_DUMP)
113 return; 113 return;
114 Str << "|" << Name << "|Inst Count |" << InstructionsEmitted << "\n"; 114 Str << "|" << Name << "|Inst Count |" << InstructionsEmitted << "\n";
115 Str << "|" << Name << "|Regs Saved |" << RegistersSaved << "\n"; 115 Str << "|" << Name << "|Regs Saved |" << RegistersSaved << "\n";
116 Str << "|" << Name << "|Frame Bytes |" << FrameBytes << "\n"; 116 Str << "|" << Name << "|Frame Bytes |" << FrameBytes << "\n";
117 Str << "|" << Name << "|Spills |" << Spills << "\n"; 117 Str << "|" << Name << "|Spills |" << Spills << "\n";
118 Str << "|" << Name << "|Fills |" << Fills << "\n"; 118 Str << "|" << Name << "|Fills |" << Fills << "\n";
119 Str << "|" << Name << "|Spills+Fills|" << Spills + Fills << "\n"; 119 Str << "|" << Name << "|Spills+Fills|" << Spills + Fills << "\n";
120 Str << "|" << Name << "|Memory Usage|"; 120 Str << "|" << Name << "|Memory Usage|";
121 if (ssize_t MemUsed = llvm::TimeRecord::getCurrentTime(false).getMemUsed()) 121 if (ssize_t MemUsed = llvm::TimeRecord::getCurrentTime(false).getMemUsed())
122 Str << MemUsed; 122 Str << MemUsed;
123 else 123 else
124 Str << "(requires '-track-memory')"; 124 Str << "(requires '-track-memory')";
125 Str << "\n"; 125 Str << "\n";
126 } 126 }
127 127
128 GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit, 128 GlobalContext::GlobalContext(Ostream *OsDump, Ostream *OsEmit,
129 ELFStreamer *ELFStr, VerboseMask Mask, 129 ELFStreamer *ELFStr, VerboseMask Mask,
130 TargetArch Arch, OptLevel Opt, 130 TargetArch Arch, OptLevel Opt,
131 IceString TestPrefix, const ClFlags &Flags) 131 IceString TestPrefix, const ClFlags &Flags)
132 : StrDump(OsDump), StrEmit(OsEmit), VMask(Mask), 132 : IsStrLocked(false), StrDump(OsDump), StrEmit(OsEmit), VMask(Mask),
133 ConstPool(new ConstantPool()), Arch(Arch), Opt(Opt), 133 ConstPool(new ConstantPool()), Arch(Arch), Opt(Opt),
134 TestPrefix(TestPrefix), Flags(Flags), RNG(""), ObjectWriter() { 134 TestPrefix(TestPrefix), Flags(Flags), RNG(""), ObjectWriter() {
135 // Create a new ThreadContext for the current thread.
136 AllThreadContexts.push_back(new ThreadContext());
JF 2015/01/15 01:31:01 Do you need to lock AllThreadContexts when doing a
Jim Stichnoth 2015/01/15 07:16:29 No since no other thread would have access to this
137 TLS = AllThreadContexts.back();
135 // Pre-register built-in stack names. 138 // Pre-register built-in stack names.
136 if (ALLOW_DUMP) { 139 if (ALLOW_DUMP) {
140 // TODO(stichnot): There needs to be a strong relationship between
141 // the newTimerStackID() return values and TSK_Default/TSK_Funcs.
137 newTimerStackID("Total across all functions"); 142 newTimerStackID("Total across all functions");
138 newTimerStackID("Per-function summary"); 143 newTimerStackID("Per-function summary");
139 } 144 }
140 if (Flags.UseELFWriter) { 145 if (Flags.UseELFWriter) {
141 ObjectWriter.reset(new ELFObjectWriter(*this, *ELFStr)); 146 ObjectWriter.reset(new ELFObjectWriter(*this, *ELFStr));
142 } 147 }
143 } 148 }
144 149
145 // Scan a string for S[0-9A-Z]*_ patterns and replace them with 150 // Scan a string for S[0-9A-Z]*_ patterns and replace them with
146 // S<num>_ where <num> is the next base-36 value. If a type name 151 // S<num>_ where <num> is the next base-36 value. If a type name
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
301 return NewName.data(); 306 return NewName.data();
302 } 307 }
303 308
304 // Transform bar ==> Prefixbar 309 // Transform bar ==> Prefixbar
305 // ^^^^^^ 310 // ^^^^^^
306 return getTestPrefix() + Name; 311 return getTestPrefix() + Name;
307 } 312 }
308 313
309 GlobalContext::~GlobalContext() { 314 GlobalContext::~GlobalContext() {
310 llvm::DeleteContainerPointers(GlobalDeclarations); 315 llvm::DeleteContainerPointers(GlobalDeclarations);
316 llvm::DeleteContainerPointers(AllThreadContexts);
311 } 317 }
312 318
319 // All locking is done by the getConstantInt[0-9]+() target function.
313 Constant *GlobalContext::getConstantInt(Type Ty, int64_t Value) { 320 Constant *GlobalContext::getConstantInt(Type Ty, int64_t Value) {
314 switch (Ty) { 321 switch (Ty) {
315 case IceType_i1: 322 case IceType_i1:
316 return getConstantInt1(Value); 323 return getConstantInt1(Value);
317 case IceType_i8: 324 case IceType_i8:
318 return getConstantInt8(Value); 325 return getConstantInt8(Value);
319 case IceType_i16: 326 case IceType_i16:
320 return getConstantInt16(Value); 327 return getConstantInt16(Value);
321 case IceType_i32: 328 case IceType_i32:
322 return getConstantInt32(Value); 329 return getConstantInt32(Value);
323 case IceType_i64: 330 case IceType_i64:
324 return getConstantInt64(Value); 331 return getConstantInt64(Value);
325 default: 332 default:
326 llvm_unreachable("Bad integer type for getConstant"); 333 llvm_unreachable("Bad integer type for getConstant");
327 } 334 }
328 return nullptr; 335 return nullptr;
329 } 336 }
330 337
331 Constant *GlobalContext::getConstantInt1(int8_t ConstantInt1) { 338 Constant *GlobalContext::getConstantInt1(int8_t ConstantInt1) {
339 std::lock_guard<GlobalLockType> L(GlobalLock);
332 ConstantInt1 &= INT8_C(1); 340 ConstantInt1 &= INT8_C(1);
333 return ConstPool->Integers1.getOrAdd(this, ConstantInt1); 341 return ConstPool->Integers1.getOrAdd(this, ConstantInt1);
334 } 342 }
335 343
336 Constant *GlobalContext::getConstantInt8(int8_t ConstantInt8) { 344 Constant *GlobalContext::getConstantInt8(int8_t ConstantInt8) {
345 std::lock_guard<GlobalLockType> L(GlobalLock);
337 return ConstPool->Integers8.getOrAdd(this, ConstantInt8); 346 return ConstPool->Integers8.getOrAdd(this, ConstantInt8);
338 } 347 }
339 348
340 Constant *GlobalContext::getConstantInt16(int16_t ConstantInt16) { 349 Constant *GlobalContext::getConstantInt16(int16_t ConstantInt16) {
350 std::lock_guard<GlobalLockType> L(GlobalLock);
341 return ConstPool->Integers16.getOrAdd(this, ConstantInt16); 351 return ConstPool->Integers16.getOrAdd(this, ConstantInt16);
342 } 352 }
343 353
344 Constant *GlobalContext::getConstantInt32(int32_t ConstantInt32) { 354 Constant *GlobalContext::getConstantInt32(int32_t ConstantInt32) {
355 std::lock_guard<GlobalLockType> L(GlobalLock);
345 return ConstPool->Integers32.getOrAdd(this, ConstantInt32); 356 return ConstPool->Integers32.getOrAdd(this, ConstantInt32);
346 } 357 }
347 358
348 Constant *GlobalContext::getConstantInt64(int64_t ConstantInt64) { 359 Constant *GlobalContext::getConstantInt64(int64_t ConstantInt64) {
360 std::lock_guard<GlobalLockType> L(GlobalLock);
349 return ConstPool->Integers64.getOrAdd(this, ConstantInt64); 361 return ConstPool->Integers64.getOrAdd(this, ConstantInt64);
350 } 362 }
351 363
352 Constant *GlobalContext::getConstantFloat(float ConstantFloat) { 364 Constant *GlobalContext::getConstantFloat(float ConstantFloat) {
365 std::lock_guard<GlobalLockType> L(GlobalLock);
353 return ConstPool->Floats.getOrAdd(this, ConstantFloat); 366 return ConstPool->Floats.getOrAdd(this, ConstantFloat);
354 } 367 }
355 368
356 Constant *GlobalContext::getConstantDouble(double ConstantDouble) { 369 Constant *GlobalContext::getConstantDouble(double ConstantDouble) {
370 std::lock_guard<GlobalLockType> L(GlobalLock);
357 return ConstPool->Doubles.getOrAdd(this, ConstantDouble); 371 return ConstPool->Doubles.getOrAdd(this, ConstantDouble);
358 } 372 }
359 373
360 Constant *GlobalContext::getConstantSym(RelocOffsetT Offset, 374 Constant *GlobalContext::getConstantSym(RelocOffsetT Offset,
361 const IceString &Name, 375 const IceString &Name,
362 bool SuppressMangling) { 376 bool SuppressMangling) {
377 std::lock_guard<GlobalLockType> L(GlobalLock);
363 return ConstPool->Relocatables.getOrAdd( 378 return ConstPool->Relocatables.getOrAdd(
364 this, RelocatableTuple(Offset, Name, SuppressMangling)); 379 this, RelocatableTuple(Offset, Name, SuppressMangling));
365 } 380 }
366 381
367 Constant *GlobalContext::getConstantUndef(Type Ty) { 382 Constant *GlobalContext::getConstantUndef(Type Ty) {
383 std::lock_guard<GlobalLockType> L(GlobalLock);
368 return ConstPool->Undefs.getOrAdd(this, Ty); 384 return ConstPool->Undefs.getOrAdd(this, Ty);
369 } 385 }
370 386
387 // All locking is done by the getConstant*() target function.
JF 2015/01/15 01:31:01 Can't all of the above known constants be create a
Jim Stichnoth 2015/01/15 07:16:29 It's true that most of the known lowering constant
371 Constant *GlobalContext::getConstantZero(Type Ty) { 388 Constant *GlobalContext::getConstantZero(Type Ty) {
372 switch (Ty) { 389 switch (Ty) {
373 case IceType_i1: 390 case IceType_i1:
374 return getConstantInt1(0); 391 return getConstantInt1(0);
375 case IceType_i8: 392 case IceType_i8:
376 return getConstantInt8(0); 393 return getConstantInt8(0);
377 case IceType_i16: 394 case IceType_i16:
378 return getConstantInt16(0); 395 return getConstantInt16(0);
379 case IceType_i32: 396 case IceType_i32:
380 return getConstantInt32(0); 397 return getConstantInt32(0);
(...skipping 15 matching lines...) Expand all
396 BaseOS << "Unsupported constant type: " << Ty; 413 BaseOS << "Unsupported constant type: " << Ty;
397 llvm_unreachable(BaseOS.str().c_str()); 414 llvm_unreachable(BaseOS.str().c_str());
398 } break; 415 } break;
399 case IceType_void: 416 case IceType_void:
400 case IceType_NUM: 417 case IceType_NUM:
401 break; 418 break;
402 } 419 }
403 llvm_unreachable("Unknown type"); 420 llvm_unreachable("Unknown type");
404 } 421 }
405 422
406 ConstantList GlobalContext::getConstantPool(Type Ty) const { 423 ConstantList GlobalContext::getConstantPool(Type Ty) {
424 std::lock_guard<GlobalLockType> L(GlobalLock);
407 switch (Ty) { 425 switch (Ty) {
408 case IceType_i1: 426 case IceType_i1:
409 case IceType_i8: 427 case IceType_i8:
410 case IceType_i16: 428 case IceType_i16:
411 case IceType_i32: 429 case IceType_i32:
412 return ConstPool->Integers32.getConstantPool(); 430 return ConstPool->Integers32.getConstantPool();
413 case IceType_i64: 431 case IceType_i64:
414 return ConstPool->Integers64.getConstantPool(); 432 return ConstPool->Integers64.getConstantPool();
415 case IceType_f32: 433 case IceType_f32:
416 return ConstPool->Floats.getConstantPool(); 434 return ConstPool->Floats.getConstantPool();
(...skipping 11 matching lines...) Expand all
428 BaseOS << "Unsupported constant type: " << Ty; 446 BaseOS << "Unsupported constant type: " << Ty;
429 llvm_unreachable(BaseOS.str().c_str()); 447 llvm_unreachable(BaseOS.str().c_str());
430 } break; 448 } break;
431 case IceType_void: 449 case IceType_void:
432 case IceType_NUM: 450 case IceType_NUM:
433 break; 451 break;
434 } 452 }
435 llvm_unreachable("Unknown type"); 453 llvm_unreachable("Unknown type");
436 } 454 }
437 455
456 // No locking because only the bitcode parser thread calls it.
438 FunctionDeclaration * 457 FunctionDeclaration *
439 GlobalContext::newFunctionDeclaration(const FuncSigType *Signature, 458 GlobalContext::newFunctionDeclaration(const FuncSigType *Signature,
440 unsigned CallingConv, unsigned Linkage, 459 unsigned CallingConv, unsigned Linkage,
441 bool IsProto) { 460 bool IsProto) {
442 FunctionDeclaration *Func = new FunctionDeclaration( 461 FunctionDeclaration *Func = new FunctionDeclaration(
443 *Signature, static_cast<llvm::CallingConv::ID>(CallingConv), 462 *Signature, static_cast<llvm::CallingConv::ID>(CallingConv),
444 static_cast<llvm::GlobalValue::LinkageTypes>(Linkage), IsProto); 463 static_cast<llvm::GlobalValue::LinkageTypes>(Linkage), IsProto);
445 GlobalDeclarations.push_back(Func); 464 GlobalDeclarations.push_back(Func);
446 return Func; 465 return Func;
447 } 466 }
448 467
468 // No locking because only the bitcode parser thread calls it.
449 VariableDeclaration *GlobalContext::newVariableDeclaration() { 469 VariableDeclaration *GlobalContext::newVariableDeclaration() {
450 VariableDeclaration *Var = new VariableDeclaration(); 470 VariableDeclaration *Var = new VariableDeclaration();
451 GlobalDeclarations.push_back(Var); 471 GlobalDeclarations.push_back(Var);
452 return Var; 472 return Var;
453 } 473 }
454 474
455 TimerIdT GlobalContext::getTimerID(TimerStackIdT StackID,
456 const IceString &Name) {
457 assert(StackID < Timers.size());
458 return Timers[StackID].getTimerID(Name);
459 }
460
461 TimerStackIdT GlobalContext::newTimerStackID(const IceString &Name) { 475 TimerStackIdT GlobalContext::newTimerStackID(const IceString &Name) {
462 if (!ALLOW_DUMP) 476 if (!ALLOW_DUMP)
463 return 0; 477 return 0;
478 std::lock_guard<GlobalLockType> L(GlobalLock);
464 TimerStackIdT NewID = Timers.size(); 479 TimerStackIdT NewID = Timers.size();
465 Timers.push_back(TimerStack(Name)); 480 Timers.push_back(TimerStack(Name));
466 return NewID; 481 return NewID;
467 } 482 }
468 483
484 TimerIdT GlobalContext::getTimerID(TimerStackIdT StackID,
485 const IceString &Name) {
486 std::lock_guard<GlobalLockType> L(GlobalLock);
487 assert(StackID < Timers.size());
488 return Timers[StackID].getTimerID(Name);
489 }
490
469 void GlobalContext::pushTimer(TimerIdT ID, TimerStackIdT StackID) { 491 void GlobalContext::pushTimer(TimerIdT ID, TimerStackIdT StackID) {
492 std::lock_guard<GlobalLockType> L(GlobalLock);
470 assert(StackID < Timers.size()); 493 assert(StackID < Timers.size());
471 Timers[StackID].push(ID); 494 Timers[StackID].push(ID);
472 } 495 }
473 496
474 void GlobalContext::popTimer(TimerIdT ID, TimerStackIdT StackID) { 497 void GlobalContext::popTimer(TimerIdT ID, TimerStackIdT StackID) {
498 std::lock_guard<GlobalLockType> L(GlobalLock);
475 assert(StackID < Timers.size()); 499 assert(StackID < Timers.size());
476 Timers[StackID].pop(ID); 500 Timers[StackID].pop(ID);
477 } 501 }
478 502
479 void GlobalContext::resetTimer(TimerStackIdT StackID) { 503 void GlobalContext::resetTimer(TimerStackIdT StackID) {
504 std::lock_guard<GlobalLockType> L(GlobalLock);
480 assert(StackID < Timers.size()); 505 assert(StackID < Timers.size());
481 Timers[StackID].reset(); 506 Timers[StackID].reset();
482 } 507 }
483 508
484 void GlobalContext::setTimerName(TimerStackIdT StackID, 509 void GlobalContext::setTimerName(TimerStackIdT StackID,
485 const IceString &NewName) { 510 const IceString &NewName) {
511 std::lock_guard<GlobalLockType> L(GlobalLock);
486 assert(StackID < Timers.size()); 512 assert(StackID < Timers.size());
487 Timers[StackID].setName(NewName); 513 Timers[StackID].setName(NewName);
488 } 514 }
489 515
490 void GlobalContext::dumpStats(const IceString &Name, bool Final) { 516 void GlobalContext::dumpStats(const IceString &Name, bool Final) {
491 if (!ALLOW_DUMP) 517 if (!ALLOW_DUMP || !getFlags().DumpStats)
492 return; 518 return;
493 if (Flags.DumpStats) { 519 std::lock_guard<GlobalLockType> L(GlobalLock);
494 if (Final) { 520 OstreamLocker OL(this);
495 StatsCumulative.dump(Name, getStrDump()); 521 if (Final) {
496 } else { 522 StatsCumulative.dump(Name, getStrDump());
497 StatsFunction.dump(Name, getStrDump()); 523 } else {
498 StatsCumulative.dump("_TOTAL_", getStrDump()); 524 TLS->StatsFunction.dump(Name, getStrDump());
499 } 525 StatsCumulative.dump("_TOTAL_", getStrDump());
500 } 526 }
501 } 527 }
502 528
503 void GlobalContext::dumpTimers(TimerStackIdT StackID, bool DumpCumulative) { 529 void GlobalContext::dumpTimers(TimerStackIdT StackID, bool DumpCumulative) {
504 if (!ALLOW_DUMP) 530 if (!ALLOW_DUMP)
505 return; 531 return;
506 assert(Timers.size() > StackID); 532 assert(Timers.size() > StackID);
533 OstreamLocker L(this);
507 Timers[StackID].dump(getStrDump(), DumpCumulative); 534 Timers[StackID].dump(getStrDump(), DumpCumulative);
508 } 535 }
509 536
510 TimerMarker::TimerMarker(TimerIdT ID, const Cfg *Func) 537 TimerMarker::TimerMarker(TimerIdT ID, const Cfg *Func)
511 : ID(ID), Ctx(Func->getContext()), Active(false) { 538 : ID(ID), Ctx(Func->getContext()), Active(false) {
512 if (ALLOW_DUMP) { 539 if (ALLOW_DUMP) {
513 Active = Func->getFocusedTiming() || Ctx->getFlags().SubzeroTimingEnabled; 540 Active = Func->getFocusedTiming() || Ctx->getFlags().SubzeroTimingEnabled;
514 if (Active) 541 if (Active)
515 Ctx->pushTimer(ID); 542 Ctx->pushTimer(ID);
516 } 543 }
517 } 544 }
518 545
546 thread_local GlobalContext::ThreadContext *GlobalContext::TLS;
547
519 } // end of namespace Ice 548 } // end of namespace Ice
OLDNEW
« src/IceGlobalContext.h ('K') | « src/IceGlobalContext.h ('k') | src/IceRegAlloc.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698