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

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 RandomShuffle(Globals.begin(), Globals.end(),
400 [this](int N) { return (uint32_t)RNG.next(N); });
John 2015/06/24 00:24:00 [RNG], instead of [this]?
qining 2015/06/24 01:20:40 Done. But also add a declaration a pointer to RNG.
401 }
397 DataLowering->lowerGlobals(Globals, SectionSuffix); 402 DataLowering->lowerGlobals(Globals, SectionSuffix);
398 for (VariableDeclaration *Var : Globals) { 403 for (VariableDeclaration *Var : Globals) {
399 Var->discardInitializers(); 404 Var->discardInitializers();
400 } 405 }
401 Globals.clear(); 406 Globals.clear();
402 } 407 }
403 408
404 void GlobalContext::lowerProfileData() { 409 void GlobalContext::lowerProfileData() {
405 // ProfileBlockInfoVarDecl is initialized in the constructor, and will only 410 // ProfileBlockInfoVarDecl is initialized in the constructor, and will only
406 // ever be nullptr after this method completes. This assertion is a convoluted 411 // ever be nullptr after this method completes. This assertion is a convoluted
(...skipping 13 matching lines...) Expand all
420 void GlobalContext::emitItems() { 425 void GlobalContext::emitItems() {
421 const bool Threaded = !getFlags().isSequential(); 426 const bool Threaded = !getFlags().isSequential();
422 // Pending is a vector containing the reassembled, ordered list of 427 // Pending is a vector containing the reassembled, ordered list of
423 // work items. When we're ready for the next item, we first check 428 // 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 429 // 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 430 // 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 431 // insert it into Pending and repeat. The work item is deleted
427 // after it is processed. 432 // after it is processed.
428 std::vector<EmitterWorkItem *> Pending; 433 std::vector<EmitterWorkItem *> Pending;
429 uint32_t DesiredSequenceNumber = getFirstSequenceNumber(); 434 uint32_t DesiredSequenceNumber = getFirstSequenceNumber();
430 while (true) { 435 uint32_t ShuffleStartIndex = DesiredSequenceNumber;
436 uint32_t ShuffleEndIndex = DesiredSequenceNumber;
437 bool EmitQueueEmpty = false;
438 uint32_t ShuffleWindowSize = getFlags().getReorderFunctionsWindowSize() > 0
John 2015/06/24 00:24:00 const uint32_t
qining 2015/06/24 01:20:40 Done.
439 ? getFlags().getReorderFunctionsWindowSize()
440 : 1;
441 bool Shuffle = Threaded ? getFlags().shouldReorderFunctions() : false;
442 while (!EmitQueueEmpty) {
431 resizePending(Pending, DesiredSequenceNumber); 443 resizePending(Pending, DesiredSequenceNumber);
432 // See if Pending contains DesiredSequenceNumber. 444 // See if Pending contains DesiredSequenceNumber.
433 EmitterWorkItem *RawItem = Pending[DesiredSequenceNumber]; 445 EmitterWorkItem *RawItem = Pending[DesiredSequenceNumber];
434 if (RawItem == nullptr) 446 if (RawItem == nullptr) {
447 // We need to fetch an EmitterWorkItem from the queue.
435 RawItem = emitQueueBlockingPop(); 448 RawItem = emitQueueBlockingPop();
436 if (RawItem == nullptr) 449 if (RawItem == nullptr) {
437 break; 450 // This is the notifier for an empty queue.
438 uint32_t ItemSeq = RawItem->getSequenceNumber(); 451 EmitQueueEmpty = true;
439 if (Threaded && ItemSeq != DesiredSequenceNumber) { 452 } else {
440 resizePending(Pending, ItemSeq); 453 // We get an EmitterWorkItem, we need to add it to Pending.
441 Pending[ItemSeq] = RawItem; 454 uint32_t ItemSeq = RawItem->getSequenceNumber();
455 if (Threaded && ItemSeq != DesiredSequenceNumber) {
456 // Not the desired one, add it to Pending but do not increase
457 // DesiredSequenceNumber. And do not emit the item.
458 resizePending(Pending, ItemSeq);
459 Pending[ItemSeq] = RawItem;
460 continue;
461 } else {
462 // ItemSeq == DesiredSequenceNumber, we need to check if we should
463 // emit it or not.
464 // Do not continue the loop here.
465 Pending[DesiredSequenceNumber] = RawItem;
466 }
467 }
468 }
469 // We have the desired EmitterWorkItem or an 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++;
475 }
476 // Continue fetching EmitterWorkItem if function reordering is turned on,
477 // and emit queue is not empty, and the number of consecutive pending items
478 // is smaller than the window size, and RawItem is not a WI_GlobalInits
479 // kind. Note we should emit WI_GlobalInits kind block first, as we need to
480 // keep the blocking profiling workflow unchanged.
481 if (Shuffle && !EmitQueueEmpty &&
482 ShuffleEndIndex - ShuffleStartIndex < ShuffleWindowSize &&
483 RawItem->getKind() != EmitterWorkItem::WI_GlobalInits)
484 // Need more EmitterWorkItem to emit.
442 continue; 485 continue;
486 // Emit the EmitterWorkItem between Pending[ShuffleStartIndex] to
487 // Pending[ShuffleEndIndex]. If function reordering turned on, shuffle the
488 // pending items from Pending[ShuffleStartIndex] to
489 // Pending[ShuffleEndIndex].
490 if (Shuffle) {
491 RandomShuffle(Pending.begin() + ShuffleStartIndex,
492 Pending.begin() + ShuffleEndIndex,
493 [this](uint64_t N) { return (uint32_t)RNG.next(N); });
443 } 494 }
444 495
445 std::unique_ptr<EmitterWorkItem> Item(RawItem); 496 // Emit the item from ShuffleStartIndex to ShuffleEndIndex.
446 ++DesiredSequenceNumber; 497 for (uint32_t I = ShuffleStartIndex; I < ShuffleEndIndex; I++) {
447 switch (Item->getKind()) { 498 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 499
457 std::unique_ptr<Assembler> Asm = Item->getAsm(); 500 switch (Item->getKind()) {
458 Asm->alignFunction(); 501 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; 502 break;
465 case FT_Iasm: { 503 case EmitterWorkItem::WI_GlobalInits: {
466 OstreamLocker L(this); 504 accumulateGlobals(Item->getGlobalInits());
467 Cfg::emitTextHeader(MangledName, this, Asm.get());
468 Asm->emitIASBytes(this);
469 } break; 505 } break;
470 case FT_Asm: 506 case EmitterWorkItem::WI_Asm: {
471 llvm::report_fatal_error("Unexpected FT_Asm"); 507 lowerGlobalsIfNoCodeHasBeenSeen();
472 break; 508 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 509
481 assert(getFlags().getOutFileType() == FT_Asm); 510 std::unique_ptr<Assembler> Asm = Item->getAsm();
482 std::unique_ptr<Cfg> Func = Item->getCfg(); 511 Asm->alignFunction();
483 // Unfortunately, we have to temporarily install the Cfg in TLS 512 IceString MangledName = mangleName(Asm->getFunctionName());
484 // because Variable::asType() uses the allocator to create the 513 switch (getFlags().getOutFileType()) {
485 // differently-typed copy. 514 case FT_Elf:
486 Cfg::setCurrentCfg(Func.get()); 515 getObjectWriter()->writeFunctionCode(MangledName, Asm->getInternal(),
487 Func->emit(); 516 Asm.get());
488 Cfg::setCurrentCfg(nullptr); 517 break;
489 dumpStats(Func->getFunctionName()); 518 case FT_Iasm: {
490 } break; 519 OstreamLocker L(this);
491 } 520 Cfg::emitTextHeader(MangledName, this, Asm.get());
492 } 521 Asm->emitIASBytes(this);
522 } break;
523 case FT_Asm:
524 llvm::report_fatal_error("Unexpected FT_Asm");
525 break;
526 } // switch (getFlags().getOutFileType())
527 } break;
528 case EmitterWorkItem::WI_Cfg: {
529 if (!ALLOW_DUMP)
530 llvm::report_fatal_error("WI_Cfg work item created inappropriately");
531 lowerGlobalsIfNoCodeHasBeenSeen();
532 accumulateGlobals(Item->getGlobalInits());
533
534 assert(getFlags().getOutFileType() == FT_Asm);
535 std::unique_ptr<Cfg> Func = Item->getCfg();
536 // Unfortunately, we have to temporarily install the Cfg in TLS
537 // because Variable::asType() uses the allocator to create the
538 // differently-typed copy.
539 Cfg::setCurrentCfg(Func.get());
540 Func->emit();
541 Cfg::setCurrentCfg(nullptr);
542 dumpStats(Func->getFunctionName());
543 } break;
544 } // switch (Item->getKind())
545 } // for loop
546 // Update the start index for next shuffling queue
547 ShuffleStartIndex = ShuffleEndIndex;
548 } // while loop
493 549
494 // In case there are no code to be generated, we invoke the conditional 550 // 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. 551 // lowerGlobals again -- this is a no-op if code has been emitted.
496 lowerGlobalsIfNoCodeHasBeenSeen(); 552 lowerGlobalsIfNoCodeHasBeenSeen();
497 } 553 }
498 554
499 // Scan a string for S[0-9A-Z]*_ patterns and replace them with 555 // 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 556 // S<num>_ where <num> is the next base-36 value. If a type name
501 // legitimately contains that pattern, then the substitution will be 557 // legitimately contains that pattern, then the substitution will be
502 // made in error and most likely the link will fail. In this case, 558 // 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
921 Ctx = Func->getContext(); 977 Ctx = Func->getContext();
922 Active = 978 Active =
923 Func->getFocusedTiming() || Ctx->getFlags().getSubzeroTimingEnabled(); 979 Func->getFocusedTiming() || Ctx->getFlags().getSubzeroTimingEnabled();
924 if (Active) 980 if (Active)
925 Ctx->pushTimer(ID, StackID); 981 Ctx->pushTimer(ID, StackID);
926 } 982 }
927 983
928 ICE_TLS_DEFINE_FIELD(GlobalContext::ThreadContext *, GlobalContext, TLS); 984 ICE_TLS_DEFINE_FIELD(GlobalContext::ThreadContext *, GlobalContext, TLS);
929 985
930 } // end of namespace Ice 986 } // end of namespace Ice
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698