OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |