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

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
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 376 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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 =
440 getFlags().getReorderFunctionsWindowSize() > 0
441 ? getFlags().getReorderFunctionsWindowSize()
442 : 1;
443 bool Shuffle = Threaded ? getFlags().shouldReorderFunctions() : false;
444 while (!EmitQueueEmpty) {
431 resizePending(Pending, DesiredSequenceNumber); 445 resizePending(Pending, DesiredSequenceNumber);
432 // See if Pending contains DesiredSequenceNumber. 446 // See if Pending contains DesiredSequenceNumber.
433 EmitterWorkItem *RawItem = Pending[DesiredSequenceNumber]; 447 EmitterWorkItem *RawItem = Pending[DesiredSequenceNumber];
434 if (RawItem == nullptr) 448 if (RawItem == nullptr) {
449 // We need to fetch an EmitterWorkItem from the queue.
435 RawItem = emitQueueBlockingPop(); 450 RawItem = emitQueueBlockingPop();
436 if (RawItem == nullptr) 451 if (RawItem == nullptr) {
437 break; 452 // This is the notifier for an empty queue.
438 uint32_t ItemSeq = RawItem->getSequenceNumber(); 453 EmitQueueEmpty = true;
439 if (Threaded && ItemSeq != DesiredSequenceNumber) { 454 } else {
440 resizePending(Pending, ItemSeq); 455 // We get an EmitterWorkItem, we need to add it to Pending.
441 Pending[ItemSeq] = RawItem; 456 uint32_t ItemSeq = RawItem->getSequenceNumber();
442 continue; 457 if (Threaded && ItemSeq != DesiredSequenceNumber) {
458 // Not the desired one, add it to Pending but do not increase
459 // DesiredSequenceNumber. Continue the loop, do not emit the item.
460 resizePending(Pending, ItemSeq);
461 Pending[ItemSeq] = RawItem;
462 continue;
463 }
464 // ItemSeq == DesiredSequenceNumber, we need to check if we should
465 // emit it or not. If !Threaded, we're OK with ItemSeq !=
466 // DesiredSequenceNumber.
467 Pending[DesiredSequenceNumber] = RawItem;
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++;
443 } 476 }
444 477
445 std::unique_ptr<EmitterWorkItem> Item(RawItem); 478 if (Shuffle) {
446 ++DesiredSequenceNumber; 479 // Continue fetching EmitterWorkItem if function reordering is turned on,
447 switch (Item->getKind()) { 480 // and emit queue is not empty, and the number of consecutive pending
448 case EmitterWorkItem::WI_Nop: 481 // items is smaller than the window size, and RawItem is not a
449 break; 482 // WI_GlobalInits kind. Emit WI_GlobalInits kind block first to avoid
450 case EmitterWorkItem::WI_GlobalInits: { 483 // holding an arbitrarily large GlobalDeclarationList.
451 accumulateGlobals(Item->getGlobalInits()); 484 if (!EmitQueueEmpty &&
452 } break; 485 ShuffleEndIndex - ShuffleStartIndex < ShuffleWindowSize &&
453 case EmitterWorkItem::WI_Asm: { 486 RawItem->getKind() != EmitterWorkItem::WI_GlobalInits)
454 lowerGlobalsIfNoCodeHasBeenSeen(); 487 continue;
455 accumulateGlobals(Item->getGlobalInits());
456 488
457 std::unique_ptr<Assembler> Asm = Item->getAsm(); 489 // Emit the EmitterWorkItem between Pending[ShuffleStartIndex] to
458 Asm->alignFunction(); 490 // Pending[ShuffleEndIndex]. If function reordering turned on, shuffle the
459 IceString MangledName = mangleName(Asm->getFunctionName()); 491 // pending items from Pending[ShuffleStartIndex] to
460 switch (getFlags().getOutFileType()) { 492 // Pending[ShuffleEndIndex].
461 case FT_Elf: 493 RandomShuffle(Pending.begin() + ShuffleStartIndex,
462 getObjectWriter()->writeFunctionCode(MangledName, Asm->getInternal(), 494 Pending.begin() + ShuffleEndIndex,
463 Asm.get()); 495 [this](uint64_t N) { return (uint32_t)RNG.next(N); });
496 }
497
498 // Emit the item from ShuffleStartIndex to ShuffleEndIndex.
499 for (uint32_t I = ShuffleStartIndex; I < ShuffleEndIndex; I++) {
500 std::unique_ptr<EmitterWorkItem> Item(Pending[I]);
501
502 switch (Item->getKind()) {
503 case EmitterWorkItem::WI_Nop:
464 break; 504 break;
465 case FT_Iasm: { 505 case EmitterWorkItem::WI_GlobalInits: {
466 OstreamLocker L(this); 506 accumulateGlobals(Item->getGlobalInits());
467 Cfg::emitTextHeader(MangledName, this, Asm.get());
468 Asm->emitIASBytes(this);
469 } break; 507 } break;
470 case FT_Asm: 508 case EmitterWorkItem::WI_Asm: {
471 llvm::report_fatal_error("Unexpected FT_Asm"); 509 lowerGlobalsIfNoCodeHasBeenSeen();
472 break; 510 accumulateGlobals(Item->getGlobalInits());
511
512 std::unique_ptr<Assembler> Asm = Item->getAsm();
513 Asm->alignFunction();
514 IceString MangledName = mangleName(Asm->getFunctionName());
515 switch (getFlags().getOutFileType()) {
516 case FT_Elf:
517 getObjectWriter()->writeFunctionCode(MangledName, Asm->getInternal(),
518 Asm.get());
519 break;
520 case FT_Iasm: {
521 OstreamLocker L(this);
522 Cfg::emitTextHeader(MangledName, this, Asm.get());
523 Asm->emitIASBytes(this);
524 } break;
525 case FT_Asm:
526 llvm::report_fatal_error("Unexpected FT_Asm");
527 break;
528 }
529 } break;
530 case EmitterWorkItem::WI_Cfg: {
531 if (!ALLOW_DUMP)
532 llvm::report_fatal_error("WI_Cfg work item created inappropriately");
533 lowerGlobalsIfNoCodeHasBeenSeen();
534 accumulateGlobals(Item->getGlobalInits());
535
536 assert(getFlags().getOutFileType() == FT_Asm);
537 std::unique_ptr<Cfg> Func = Item->getCfg();
538 // Unfortunately, we have to temporarily install the Cfg in TLS
539 // because Variable::asType() uses the allocator to create the
540 // differently-typed copy.
541 Cfg::setCurrentCfg(Func.get());
542 Func->emit();
543 Cfg::setCurrentCfg(nullptr);
544 dumpStats(Func->getFunctionName());
545 } break;
473 } 546 }
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
481 assert(getFlags().getOutFileType() == FT_Asm);
482 std::unique_ptr<Cfg> Func = Item->getCfg();
483 // Unfortunately, we have to temporarily install the Cfg in TLS
484 // because Variable::asType() uses the allocator to create the
485 // differently-typed copy.
486 Cfg::setCurrentCfg(Func.get());
487 Func->emit();
488 Cfg::setCurrentCfg(nullptr);
489 dumpStats(Func->getFunctionName());
490 } break;
491 } 547 }
548 // Update the start index for next shuffling queue
549 ShuffleStartIndex = ShuffleEndIndex;
492 } 550 }
493 551
494 // In case there are no code to be generated, we invoke the conditional 552 // 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. 553 // lowerGlobals again -- this is a no-op if code has been emitted.
496 lowerGlobalsIfNoCodeHasBeenSeen(); 554 lowerGlobalsIfNoCodeHasBeenSeen();
497 } 555 }
498 556
499 // Scan a string for S[0-9A-Z]*_ patterns and replace them with 557 // 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 558 // S<num>_ where <num> is the next base-36 value. If a type name
501 // legitimately contains that pattern, then the substitution will be 559 // legitimately contains that pattern, then the substitution will be
(...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after
921 Ctx = Func->getContext(); 979 Ctx = Func->getContext();
922 Active = 980 Active =
923 Func->getFocusedTiming() || Ctx->getFlags().getSubzeroTimingEnabled(); 981 Func->getFocusedTiming() || Ctx->getFlags().getSubzeroTimingEnabled();
924 if (Active) 982 if (Active)
925 Ctx->pushTimer(ID, StackID); 983 Ctx->pushTimer(ID, StackID);
926 } 984 }
927 985
928 ICE_TLS_DEFINE_FIELD(GlobalContext::ThreadContext *, GlobalContext, TLS); 986 ICE_TLS_DEFINE_FIELD(GlobalContext::ThreadContext *, GlobalContext, TLS);
929 987
930 } // end of namespace Ice 988 } // end of namespace Ice
OLDNEW
« src/IceClFlags.cpp ('K') | « src/IceELFObjectWriter.cpp ('k') | src/IceTargetLowering.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698