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

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: fixed some comments in patch set 1 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 = 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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698