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

Side by Side Diff: src/IceGlobalContext.cpp

Issue 1206723003: Function Layout, Global Variable Layout and Pooled Constants Layout Reordering (Closed) Base URL: https://chromium.googlesource.com/native_client/pnacl-subzero.git@master
Patch Set: Created 5 years, 6 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/IceELFObjectWriter.cpp ('k') | src/IceGlobalInits.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 // This file defines aspects of the compilation that persist across 10 // This file defines aspects of the compilation that persist across
11 // multiple functions. 11 // multiple functions.
12 // 12 //
13 //===----------------------------------------------------------------------===// 13 //===----------------------------------------------------------------------===//
14 14
15 #include "IceGlobalContext.h" 15 #include "IceGlobalContext.h"
16 16
17 #include "IceCfg.h" 17 #include "IceCfg.h"
18 #include "IceCfgNode.h" 18 #include "IceCfgNode.h"
19 #include "IceClFlags.h" 19 #include "IceClFlags.h"
20 #include "IceDefs.h" 20 #include "IceDefs.h"
21 #include "IceELFObjectWriter.h" 21 #include "IceELFObjectWriter.h"
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 <algorithm> // max()
30 #include <cctype> // isdigit(), isupper()
30 #include <locale> // locale 31 #include <locale> // locale
31 #include <unordered_map> 32 #include <unordered_map>
32 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
43 namespace Ice { 43 namespace Ice {
(...skipping 344 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
OLDNEW
« no previous file with comments | « src/IceELFObjectWriter.cpp ('k') | src/IceGlobalInits.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698