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 11 matching lines...) Expand all Loading... | |
| 22 #include "IceGlobalInits.h" | 22 #include "IceGlobalInits.h" |
| 23 #include "IceOperand.h" | 23 #include "IceOperand.h" |
| 24 #include "IceTargetLowering.h" | 24 #include "IceTargetLowering.h" |
| 25 #include "IceTimerTree.h" | 25 #include "IceTimerTree.h" |
| 26 #include "IceTypes.h" | 26 #include "IceTypes.h" |
| 27 #include "llvm/Support/Timer.h" | 27 #include "llvm/Support/Timer.h" |
| 28 | 28 |
| 29 #include <ctype.h> // isdigit(), isupper() | 29 #include <ctype.h> // isdigit(), isupper() |
| 30 #include <locale> // locale | 30 #include <locale> // locale |
| 31 #include <unordered_map> | 31 #include <unordered_map> |
| 32 | 32 #include <algorithm> |
|
Jim Stichnoth
2015/06/26 06:14:42
Sort this alphabetically, i.e. above ctype.h.
And
qining
2015/06/26 16:20:14
Done.
| |
| 33 | 33 |
| 34 namespace std { | 34 namespace std { |
| 35 template <> struct hash<Ice::RelocatableTuple> { | 35 template <> struct hash<Ice::RelocatableTuple> { |
| 36 size_t operator()(const Ice::RelocatableTuple &Key) const { | 36 size_t operator()(const Ice::RelocatableTuple &Key) const { |
| 37 return hash<Ice::IceString>()(Key.Name) + | 37 return hash<Ice::IceString>()(Key.Name) + |
| 38 hash<Ice::RelocOffsetT>()(Key.Offset); | 38 hash<Ice::RelocOffsetT>()(Key.Offset); |
| 39 } | 39 } |
| 40 }; | 40 }; |
| 41 } // end of namespace std | 41 } // end of namespace std |
| 42 | 42 |
| (...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 388 OstreamLocker L(this); | 388 OstreamLocker L(this); |
| 389 Ostream &Stream = getStrDump(); | 389 Ostream &Stream = getStrDump(); |
| 390 for (const Ice::VariableDeclaration *Global : Globals) { | 390 for (const Ice::VariableDeclaration *Global : Globals) { |
| 391 Global->dump(this, Stream); | 391 Global->dump(this, Stream); |
| 392 } | 392 } |
| 393 } | 393 } |
| 394 if (Flags.getDisableTranslation()) | 394 if (Flags.getDisableTranslation()) |
| 395 return; | 395 return; |
| 396 | 396 |
| 397 addBlockInfoPtrs(Globals, ProfileBlockInfoVarDecl); | 397 addBlockInfoPtrs(Globals, ProfileBlockInfoVarDecl); |
| 398 // If we need to shuffle the layout of global variables, shuffle them now. | |
| 399 if (getFlags().shouldReorderGlobalVariables()) { | |
| 400 auto *RNGPtr = &RNG; | |
| 401 RandomShuffle(Globals.begin(), Globals.end(), | |
| 402 [RNGPtr](int N) { return (uint32_t)RNGPtr->next(N); }); | |
| 403 } | |
| 398 DataLowering->lowerGlobals(Globals, SectionSuffix); | 404 DataLowering->lowerGlobals(Globals, SectionSuffix); |
| 399 for (VariableDeclaration *Var : Globals) { | 405 for (VariableDeclaration *Var : Globals) { |
| 400 Var->discardInitializers(); | 406 Var->discardInitializers(); |
| 401 } | 407 } |
| 402 Globals.clear(); | 408 Globals.clear(); |
| 403 } | 409 } |
| 404 | 410 |
| 405 void GlobalContext::lowerProfileData() { | 411 void GlobalContext::lowerProfileData() { |
| 406 // ProfileBlockInfoVarDecl is initialized in the constructor, and will only | 412 // ProfileBlockInfoVarDecl is initialized in the constructor, and will only |
| 407 // ever be nullptr after this method completes. This assertion is a convoluted | 413 // ever be nullptr after this method completes. This assertion is a convoluted |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 421 void GlobalContext::emitItems() { | 427 void GlobalContext::emitItems() { |
| 422 const bool Threaded = !getFlags().isSequential(); | 428 const bool Threaded = !getFlags().isSequential(); |
| 423 // Pending is a vector containing the reassembled, ordered list of | 429 // Pending is a vector containing the reassembled, ordered list of |
| 424 // work items. When we're ready for the next item, we first check | 430 // work items. When we're ready for the next item, we first check |
| 425 // whether it's in the Pending list. If not, we take an item from | 431 // whether it's in the Pending list. If not, we take an item from |
| 426 // the work queue, and if it's not the item we're waiting for, we | 432 // the work queue, and if it's not the item we're waiting for, we |
| 427 // insert it into Pending and repeat. The work item is deleted | 433 // insert it into Pending and repeat. The work item is deleted |
| 428 // after it is processed. | 434 // after it is processed. |
| 429 std::vector<EmitterWorkItem *> Pending; | 435 std::vector<EmitterWorkItem *> Pending; |
| 430 uint32_t DesiredSequenceNumber = getFirstSequenceNumber(); | 436 uint32_t DesiredSequenceNumber = getFirstSequenceNumber(); |
| 431 while (true) { | 437 uint32_t ShuffleStartIndex = DesiredSequenceNumber; |
| 438 uint32_t ShuffleEndIndex = DesiredSequenceNumber; | |
| 439 bool EmitQueueEmpty = false; | |
| 440 const uint32_t ShuffleWindowSize = | |
| 441 std::max(1u, getFlags().getReorderFunctionsWindowSize()); | |
| 442 bool Shuffle = Threaded && getFlags().shouldReorderFunctions(); | |
| 443 while (!EmitQueueEmpty) { | |
| 432 resizePending(Pending, DesiredSequenceNumber); | 444 resizePending(Pending, DesiredSequenceNumber); |
| 433 // See if Pending contains DesiredSequenceNumber. | 445 // See if Pending contains DesiredSequenceNumber. |
| 434 EmitterWorkItem *RawItem = Pending[DesiredSequenceNumber]; | 446 EmitterWorkItem *RawItem = Pending[DesiredSequenceNumber]; |
| 435 if (RawItem == nullptr) | 447 if (RawItem == nullptr) { |
| 448 // We need to fetch an EmitterWorkItem from the queue. | |
| 436 RawItem = emitQueueBlockingPop(); | 449 RawItem = emitQueueBlockingPop(); |
| 437 if (RawItem == nullptr) | 450 if (RawItem == nullptr) { |
| 438 break; | 451 // This is the notifier for an empty queue. |
| 439 uint32_t ItemSeq = RawItem->getSequenceNumber(); | 452 EmitQueueEmpty = true; |
| 440 if (Threaded && ItemSeq != DesiredSequenceNumber) { | 453 } else { |
| 441 resizePending(Pending, ItemSeq); | 454 // We get an EmitterWorkItem, we need to add it to Pending. |
| 442 Pending[ItemSeq] = RawItem; | 455 uint32_t ItemSeq = RawItem->getSequenceNumber(); |
| 443 continue; | 456 if (Threaded && ItemSeq != DesiredSequenceNumber) { |
| 457 // Not the desired one, add it to Pending but do not increase | |
| 458 // DesiredSequenceNumber. Continue the loop, do not emit the item. | |
| 459 resizePending(Pending, ItemSeq); | |
| 460 Pending[ItemSeq] = RawItem; | |
| 461 continue; | |
| 462 } | |
| 463 // ItemSeq == DesiredSequenceNumber, we need to check if we should | |
| 464 // emit it or not. If !Threaded, we're OK with ItemSeq != | |
| 465 // DesiredSequenceNumber. | |
| 466 Pending[DesiredSequenceNumber] = RawItem; | |
| 467 } | |
| 468 } | |
| 469 // We have the desired EmitterWorkItem or nullptr as the end notifier. | |
| 470 // If the emitter queue is not empty, increase DesiredSequenceNumber and | |
| 471 // ShuffleEndIndex. | |
| 472 if (!EmitQueueEmpty) { | |
| 473 DesiredSequenceNumber++; | |
| 474 ShuffleEndIndex++; | |
| 444 } | 475 } |
| 445 | 476 |
| 446 std::unique_ptr<EmitterWorkItem> Item(RawItem); | 477 if (Shuffle) { |
| 447 ++DesiredSequenceNumber; | 478 // Continue fetching EmitterWorkItem if function reordering is turned on, |
| 448 switch (Item->getKind()) { | 479 // and emit queue is not empty, and the number of consecutive pending |
| 449 case EmitterWorkItem::WI_Nop: | 480 // items is smaller than the window size, and RawItem is not a |
| 450 break; | 481 // WI_GlobalInits kind. Emit WI_GlobalInits kind block first to avoid |
| 451 case EmitterWorkItem::WI_GlobalInits: { | 482 // holding an arbitrarily large GlobalDeclarationList. |
| 452 accumulateGlobals(Item->getGlobalInits()); | 483 if (!EmitQueueEmpty && |
| 453 } break; | 484 ShuffleEndIndex - ShuffleStartIndex < ShuffleWindowSize && |
| 454 case EmitterWorkItem::WI_Asm: { | 485 RawItem->getKind() != EmitterWorkItem::WI_GlobalInits) |
| 455 lowerGlobalsIfNoCodeHasBeenSeen(); | 486 continue; |
| 456 accumulateGlobals(Item->getGlobalInits()); | |
| 457 | 487 |
| 458 std::unique_ptr<Assembler> Asm = Item->getAsm(); | 488 // Emit the EmitterWorkItem between Pending[ShuffleStartIndex] to |
| 459 Asm->alignFunction(); | 489 // Pending[ShuffleEndIndex]. If function reordering turned on, shuffle the |
| 460 IceString MangledName = mangleName(Asm->getFunctionName()); | 490 // pending items from Pending[ShuffleStartIndex] to |
| 461 switch (getFlags().getOutFileType()) { | 491 // Pending[ShuffleEndIndex]. |
| 462 case FT_Elf: | 492 RandomShuffle(Pending.begin() + ShuffleStartIndex, |
| 463 getObjectWriter()->writeFunctionCode(MangledName, Asm->getInternal(), | 493 Pending.begin() + ShuffleEndIndex, |
| 464 Asm.get()); | 494 [this](uint64_t N) { return (uint32_t)RNG.next(N); }); |
| 495 } | |
| 496 | |
| 497 // Emit the item from ShuffleStartIndex to ShuffleEndIndex. | |
| 498 for (uint32_t I = ShuffleStartIndex; I < ShuffleEndIndex; I++) { | |
| 499 std::unique_ptr<EmitterWorkItem> Item(Pending[I]); | |
| 500 | |
| 501 switch (Item->getKind()) { | |
| 502 case EmitterWorkItem::WI_Nop: | |
| 465 break; | 503 break; |
| 466 case FT_Iasm: { | 504 case EmitterWorkItem::WI_GlobalInits: { |
| 467 OstreamLocker L(this); | 505 accumulateGlobals(Item->getGlobalInits()); |
| 468 Cfg::emitTextHeader(MangledName, this, Asm.get()); | |
| 469 Asm->emitIASBytes(this); | |
| 470 } break; | 506 } break; |
| 471 case FT_Asm: | 507 case EmitterWorkItem::WI_Asm: { |
| 472 llvm::report_fatal_error("Unexpected FT_Asm"); | 508 lowerGlobalsIfNoCodeHasBeenSeen(); |
| 473 break; | 509 accumulateGlobals(Item->getGlobalInits()); |
| 510 | |
| 511 std::unique_ptr<Assembler> Asm = Item->getAsm(); | |
| 512 Asm->alignFunction(); | |
| 513 IceString MangledName = mangleName(Asm->getFunctionName()); | |
| 514 switch (getFlags().getOutFileType()) { | |
| 515 case FT_Elf: | |
| 516 getObjectWriter()->writeFunctionCode(MangledName, Asm->getInternal(), | |
| 517 Asm.get()); | |
| 518 break; | |
| 519 case FT_Iasm: { | |
| 520 OstreamLocker L(this); | |
| 521 Cfg::emitTextHeader(MangledName, this, Asm.get()); | |
| 522 Asm->emitIASBytes(this); | |
| 523 } break; | |
| 524 case FT_Asm: | |
| 525 llvm::report_fatal_error("Unexpected FT_Asm"); | |
| 526 break; | |
| 527 } | |
| 528 } break; | |
| 529 case EmitterWorkItem::WI_Cfg: { | |
| 530 if (!BuildDefs::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; | |
| 474 } | 545 } |
| 475 } break; | |
| 476 case EmitterWorkItem::WI_Cfg: { | |
| 477 if (!BuildDefs::dump()) | |
| 478 llvm::report_fatal_error("WI_Cfg work item created inappropriately"); | |
| 479 lowerGlobalsIfNoCodeHasBeenSeen(); | |
| 480 accumulateGlobals(Item->getGlobalInits()); | |
| 481 | |
| 482 assert(getFlags().getOutFileType() == FT_Asm); | |
| 483 std::unique_ptr<Cfg> Func = Item->getCfg(); | |
| 484 // Unfortunately, we have to temporarily install the Cfg in TLS | |
| 485 // because Variable::asType() uses the allocator to create the | |
| 486 // differently-typed copy. | |
| 487 Cfg::setCurrentCfg(Func.get()); | |
| 488 Func->emit(); | |
| 489 Cfg::setCurrentCfg(nullptr); | |
| 490 dumpStats(Func->getFunctionName()); | |
| 491 } break; | |
| 492 } | 546 } |
| 547 // Update the start index for next shuffling queue | |
| 548 ShuffleStartIndex = ShuffleEndIndex; | |
| 493 } | 549 } |
| 494 | 550 |
| 495 // 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 |
| 496 // 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. |
| 497 lowerGlobalsIfNoCodeHasBeenSeen(); | 553 lowerGlobalsIfNoCodeHasBeenSeen(); |
| 498 } | 554 } |
| 499 | 555 |
| 500 // 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 |
| 501 // 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 |
| 502 // legitimately contains that pattern, then the substitution will be | 558 // legitimately contains that pattern, then the substitution will be |
| (...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 922 Ctx = Func->getContext(); | 978 Ctx = Func->getContext(); |
| 923 Active = | 979 Active = |
| 924 Func->getFocusedTiming() || Ctx->getFlags().getSubzeroTimingEnabled(); | 980 Func->getFocusedTiming() || Ctx->getFlags().getSubzeroTimingEnabled(); |
| 925 if (Active) | 981 if (Active) |
| 926 Ctx->pushTimer(ID, StackID); | 982 Ctx->pushTimer(ID, StackID); |
| 927 } | 983 } |
| 928 | 984 |
| 929 ICE_TLS_DEFINE_FIELD(GlobalContext::ThreadContext *, GlobalContext, TLS); | 985 ICE_TLS_DEFINE_FIELD(GlobalContext::ThreadContext *, GlobalContext, TLS); |
| 930 | 986 |
| 931 } // end of namespace Ice | 987 } // end of namespace Ice |
| OLD | NEW |