Chromium Code Reviews| 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 376 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 387 OstreamLocker L(this); | 387 OstreamLocker L(this); |
| 388 Ostream &Stream = getStrDump(); | 388 Ostream &Stream = getStrDump(); |
| 389 for (const Ice::VariableDeclaration *Global : Globals) { | 389 for (const Ice::VariableDeclaration *Global : Globals) { |
| 390 Global->dump(this, Stream); | 390 Global->dump(this, Stream); |
| 391 } | 391 } |
| 392 } | 392 } |
| 393 if (Flags.getDisableTranslation()) | 393 if (Flags.getDisableTranslation()) |
| 394 return; | 394 return; |
| 395 | 395 |
| 396 addBlockInfoPtrs(Globals, ProfileBlockInfoVarDecl); | 396 addBlockInfoPtrs(Globals, ProfileBlockInfoVarDecl); |
| 397 // If we need to shuffle the layout of global variables, shuffle them now. | |
| 398 if (getFlags().shouldReorderGlobalVariables()) { | |
| 399 auto* RNGPtr = &RNG; | |
| 400 RandomShuffle(Globals.begin(), Globals.end(), | |
| 401 [RNGPtr](int N) { return (uint32_t)RNGPtr->next(N); }); | |
| 402 } | |
| 397 DataLowering->lowerGlobals(Globals, SectionSuffix); | 403 DataLowering->lowerGlobals(Globals, SectionSuffix); |
| 398 for (VariableDeclaration *Var : Globals) { | 404 for (VariableDeclaration *Var : Globals) { |
| 399 Var->discardInitializers(); | 405 Var->discardInitializers(); |
| 400 } | 406 } |
| 401 Globals.clear(); | 407 Globals.clear(); |
| 402 } | 408 } |
| 403 | 409 |
| 404 void GlobalContext::lowerProfileData() { | 410 void GlobalContext::lowerProfileData() { |
| 405 // ProfileBlockInfoVarDecl is initialized in the constructor, and will only | 411 // ProfileBlockInfoVarDecl is initialized in the constructor, and will only |
| 406 // ever be nullptr after this method completes. This assertion is a convoluted | 412 // ever be nullptr after this method completes. This assertion is a convoluted |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 420 void GlobalContext::emitItems() { | 426 void GlobalContext::emitItems() { |
| 421 const bool Threaded = !getFlags().isSequential(); | 427 const bool Threaded = !getFlags().isSequential(); |
| 422 // Pending is a vector containing the reassembled, ordered list of | 428 // Pending is a vector containing the reassembled, ordered list of |
| 423 // work items. When we're ready for the next item, we first check | 429 // work items. When we're ready for the next item, we first check |
| 424 // whether it's in the Pending list. If not, we take an item from | 430 // whether it's in the Pending list. If not, we take an item from |
| 425 // the work queue, and if it's not the item we're waiting for, we | 431 // the work queue, and if it's not the item we're waiting for, we |
| 426 // insert it into Pending and repeat. The work item is deleted | 432 // insert it into Pending and repeat. The work item is deleted |
| 427 // after it is processed. | 433 // after it is processed. |
| 428 std::vector<EmitterWorkItem *> Pending; | 434 std::vector<EmitterWorkItem *> Pending; |
| 429 uint32_t DesiredSequenceNumber = getFirstSequenceNumber(); | 435 uint32_t DesiredSequenceNumber = getFirstSequenceNumber(); |
| 430 while (true) { | 436 uint32_t ShuffleStartIndex = DesiredSequenceNumber; |
| 437 uint32_t ShuffleEndIndex = DesiredSequenceNumber; | |
| 438 bool EmitQueueEmpty = false; | |
| 439 const uint32_t ShuffleWindowSize = getFlags().getReorderFunctionsWindowSize() > 0 | |
|
John
2015/06/24 08:15:54
line length > 80 chars.
qining
2015/06/24 17:17:20
Done.
| |
| 440 ? getFlags().getReorderFunctionsWindowSize() | |
| 441 : 1; | |
| 442 bool Shuffle = Threaded ? getFlags().shouldReorderFunctions() : false; | |
| 443 while (!EmitQueueEmpty) { | |
| 431 resizePending(Pending, DesiredSequenceNumber); | 444 resizePending(Pending, DesiredSequenceNumber); |
| 432 // See if Pending contains DesiredSequenceNumber. | 445 // See if Pending contains DesiredSequenceNumber. |
| 433 EmitterWorkItem *RawItem = Pending[DesiredSequenceNumber]; | 446 EmitterWorkItem *RawItem = Pending[DesiredSequenceNumber]; |
| 434 if (RawItem == nullptr) | 447 if (RawItem == nullptr) { |
| 448 // We need to fetch an EmitterWorkItem from the queue. | |
| 435 RawItem = emitQueueBlockingPop(); | 449 RawItem = emitQueueBlockingPop(); |
| 436 if (RawItem == nullptr) | 450 if (RawItem == nullptr) { |
| 437 break; | 451 // This is the notifier for an empty queue. |
| 438 uint32_t ItemSeq = RawItem->getSequenceNumber(); | 452 EmitQueueEmpty = true; |
| 439 if (Threaded && ItemSeq != DesiredSequenceNumber) { | 453 } else { |
| 440 resizePending(Pending, ItemSeq); | 454 // We get an EmitterWorkItem, we need to add it to Pending. |
| 441 Pending[ItemSeq] = RawItem; | 455 uint32_t ItemSeq = RawItem->getSequenceNumber(); |
|
John
2015/06/24 08:15:55
Optional: I would define ItemSet in line 450, and
qining
2015/06/24 17:17:20
But there is a problem, RawItem may be a null poin
John
2015/06/24 17:31:48
Oh, the wonders of early morning coding... =/ neve
| |
| 456 if (Threaded && ItemSeq != DesiredSequenceNumber) { | |
| 457 // Not the desired one, add it to Pending but do not increase | |
| 458 // DesiredSequenceNumber. And do not emit the item. | |
| 459 resizePending(Pending, ItemSeq); | |
| 460 Pending[ItemSeq] = RawItem; | |
| 461 continue; | |
| 462 } else { | |
| 463 // ItemSeq == DesiredSequenceNumber, we need to check if we should | |
|
John
2015/06/24 08:15:54
Not necessarily. This else branch will be executed
qining
2015/06/24 17:17:20
Yes, you are right, this enclosing else is not nec
John
2015/06/24 17:31:48
I was pointing out that the comment is not accurat
qining
2015/06/24 20:18:56
Done. Yes, the original comment is not accurate, I
| |
| 464 // emit it or not. | |
| 465 // Do not continue the loop here. | |
| 466 Pending[DesiredSequenceNumber] = RawItem; | |
| 467 } | |
| 468 } | |
| 469 } | |
| 470 // We have the desired EmitterWorkItem or an nullptr as the end notifier. | |
| 471 // If the emitter queue is not empty, increase DesiredSequenceNumber and | |
| 472 // ShuffleEndIndex. | |
| 473 if (!EmitQueueEmpty) { | |
| 474 DesiredSequenceNumber++; | |
| 475 ShuffleEndIndex++; | |
| 476 } | |
| 477 // Continue fetching EmitterWorkItem if function reordering is turned on, | |
| 478 // and emit queue is not empty, and the number of consecutive pending items | |
| 479 // is smaller than the window size, and RawItem is not a WI_GlobalInits | |
| 480 // kind. Note we should emit WI_GlobalInits kind block first, as we need to | |
| 481 // keep the blocking profiling workflow unchanged. | |
|
John
2015/06/24 08:15:55
There's nothing in the block profiling requiring t
qining
2015/06/24 17:17:20
Yes, you are right, the problem is actually the lo
John
2015/06/24 17:31:49
Not just that, we don't want to keep an arbitraril
qining
2015/06/24 20:18:56
Done. I do think this is more of a communication p
| |
| 482 if (Shuffle && !EmitQueueEmpty && | |
|
John
2015/06/24 08:15:55
Personally, I think this would be easier to read:
qining
2015/06/24 17:17:20
Done.
| |
| 483 ShuffleEndIndex - ShuffleStartIndex < ShuffleWindowSize && | |
| 484 RawItem->getKind() != EmitterWorkItem::WI_GlobalInits) | |
| 485 // Need more EmitterWorkItem to emit. | |
| 442 continue; | 486 continue; |
| 487 // Emit the EmitterWorkItem between Pending[ShuffleStartIndex] to | |
| 488 // Pending[ShuffleEndIndex]. If function reordering turned on, shuffle the | |
| 489 // pending items from Pending[ShuffleStartIndex] to | |
| 490 // Pending[ShuffleEndIndex]. | |
| 491 if (Shuffle) { | |
| 492 RandomShuffle(Pending.begin() + ShuffleStartIndex, | |
| 493 Pending.begin() + ShuffleEndIndex, | |
| 494 [this](uint64_t N) { return (uint32_t)RNG.next(N); }); | |
| 443 } | 495 } |
| 444 | 496 |
| 445 std::unique_ptr<EmitterWorkItem> Item(RawItem); | 497 // Emit the item from ShuffleStartIndex to ShuffleEndIndex. |
| 446 ++DesiredSequenceNumber; | 498 for (uint32_t I = ShuffleStartIndex; I < ShuffleEndIndex; I++) { |
| 447 switch (Item->getKind()) { | 499 std::unique_ptr<EmitterWorkItem> Item(Pending[I]); |
| 448 case EmitterWorkItem::WI_Nop: | |
| 449 break; | |
| 450 case EmitterWorkItem::WI_GlobalInits: { | |
| 451 accumulateGlobals(Item->getGlobalInits()); | |
| 452 } break; | |
| 453 case EmitterWorkItem::WI_Asm: { | |
| 454 lowerGlobalsIfNoCodeHasBeenSeen(); | |
| 455 accumulateGlobals(Item->getGlobalInits()); | |
| 456 | 500 |
| 457 std::unique_ptr<Assembler> Asm = Item->getAsm(); | 501 switch (Item->getKind()) { |
| 458 Asm->alignFunction(); | 502 case EmitterWorkItem::WI_Nop: |
| 459 IceString MangledName = mangleName(Asm->getFunctionName()); | |
| 460 switch (getFlags().getOutFileType()) { | |
| 461 case FT_Elf: | |
| 462 getObjectWriter()->writeFunctionCode(MangledName, Asm->getInternal(), | |
| 463 Asm.get()); | |
| 464 break; | 503 break; |
| 465 case FT_Iasm: { | 504 case EmitterWorkItem::WI_GlobalInits: { |
| 466 OstreamLocker L(this); | 505 accumulateGlobals(Item->getGlobalInits()); |
| 467 Cfg::emitTextHeader(MangledName, this, Asm.get()); | |
| 468 Asm->emitIASBytes(this); | |
| 469 } break; | 506 } break; |
| 470 case FT_Asm: | 507 case EmitterWorkItem::WI_Asm: { |
| 471 llvm::report_fatal_error("Unexpected FT_Asm"); | 508 lowerGlobalsIfNoCodeHasBeenSeen(); |
| 472 break; | 509 accumulateGlobals(Item->getGlobalInits()); |
| 473 } | |
| 474 } break; | |
| 475 case EmitterWorkItem::WI_Cfg: { | |
| 476 if (!ALLOW_DUMP) | |
| 477 llvm::report_fatal_error("WI_Cfg work item created inappropriately"); | |
| 478 lowerGlobalsIfNoCodeHasBeenSeen(); | |
| 479 accumulateGlobals(Item->getGlobalInits()); | |
| 480 | 510 |
| 481 assert(getFlags().getOutFileType() == FT_Asm); | 511 std::unique_ptr<Assembler> Asm = Item->getAsm(); |
| 482 std::unique_ptr<Cfg> Func = Item->getCfg(); | 512 Asm->alignFunction(); |
| 483 // Unfortunately, we have to temporarily install the Cfg in TLS | 513 IceString MangledName = mangleName(Asm->getFunctionName()); |
| 484 // because Variable::asType() uses the allocator to create the | 514 switch (getFlags().getOutFileType()) { |
| 485 // differently-typed copy. | 515 case FT_Elf: |
| 486 Cfg::setCurrentCfg(Func.get()); | 516 getObjectWriter()->writeFunctionCode(MangledName, Asm->getInternal(), |
| 487 Func->emit(); | 517 Asm.get()); |
| 488 Cfg::setCurrentCfg(nullptr); | 518 break; |
| 489 dumpStats(Func->getFunctionName()); | 519 case FT_Iasm: { |
| 490 } break; | 520 OstreamLocker L(this); |
| 491 } | 521 Cfg::emitTextHeader(MangledName, this, Asm.get()); |
| 492 } | 522 Asm->emitIASBytes(this); |
| 523 } break; | |
| 524 case FT_Asm: | |
| 525 llvm::report_fatal_error("Unexpected FT_Asm"); | |
| 526 break; | |
| 527 } // switch (getFlags().getOutFileType()) | |
| 528 } break; | |
| 529 case EmitterWorkItem::WI_Cfg: { | |
| 530 if (!ALLOW_DUMP) | |
| 531 llvm::report_fatal_error("WI_Cfg work item created inappropriately"); | |
| 532 lowerGlobalsIfNoCodeHasBeenSeen(); | |
| 533 accumulateGlobals(Item->getGlobalInits()); | |
| 534 | |
| 535 assert(getFlags().getOutFileType() == FT_Asm); | |
| 536 std::unique_ptr<Cfg> Func = Item->getCfg(); | |
| 537 // Unfortunately, we have to temporarily install the Cfg in TLS | |
| 538 // because Variable::asType() uses the allocator to create the | |
| 539 // differently-typed copy. | |
| 540 Cfg::setCurrentCfg(Func.get()); | |
| 541 Func->emit(); | |
| 542 Cfg::setCurrentCfg(nullptr); | |
| 543 dumpStats(Func->getFunctionName()); | |
| 544 } break; | |
| 545 } // switch (Item->getKind()) | |
|
John
2015/06/24 08:15:54
Just an observation, I don't see a whole lot of su
qining
2015/06/24 17:17:20
Should I remove these labels?
John
2015/06/24 17:31:49
I am totally fine with them, I was mostly pointing
qining
2015/06/24 20:18:56
Done. Just removed them, they look more likely my
| |
| 546 } // for loop | |
| 547 // Update the start index for next shuffling queue | |
| 548 ShuffleStartIndex = ShuffleEndIndex; | |
| 549 } // while loop | |
| 493 | 550 |
| 494 // In case there are no code to be generated, we invoke the conditional | 551 // In case there are no code to be generated, we invoke the conditional |
| 495 // lowerGlobals again -- this is a no-op if code has been emitted. | 552 // lowerGlobals again -- this is a no-op if code has been emitted. |
| 496 lowerGlobalsIfNoCodeHasBeenSeen(); | 553 lowerGlobalsIfNoCodeHasBeenSeen(); |
| 497 } | 554 } |
| 498 | 555 |
| 499 // Scan a string for S[0-9A-Z]*_ patterns and replace them with | 556 // Scan a string for S[0-9A-Z]*_ patterns and replace them with |
| 500 // S<num>_ where <num> is the next base-36 value. If a type name | 557 // S<num>_ where <num> is the next base-36 value. If a type name |
| 501 // legitimately contains that pattern, then the substitution will be | 558 // legitimately contains that pattern, then the substitution will be |
| 502 // made in error and most likely the link will fail. In this case, | 559 // made in error and most likely the link will fail. In this case, |
| (...skipping 418 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 921 Ctx = Func->getContext(); | 978 Ctx = Func->getContext(); |
| 922 Active = | 979 Active = |
| 923 Func->getFocusedTiming() || Ctx->getFlags().getSubzeroTimingEnabled(); | 980 Func->getFocusedTiming() || Ctx->getFlags().getSubzeroTimingEnabled(); |
| 924 if (Active) | 981 if (Active) |
| 925 Ctx->pushTimer(ID, StackID); | 982 Ctx->pushTimer(ID, StackID); |
| 926 } | 983 } |
| 927 | 984 |
| 928 ICE_TLS_DEFINE_FIELD(GlobalContext::ThreadContext *, GlobalContext, TLS); | 985 ICE_TLS_DEFINE_FIELD(GlobalContext::ThreadContext *, GlobalContext, TLS); |
| 929 | 986 |
| 930 } // end of namespace Ice | 987 } // end of namespace Ice |
| OLD | NEW |