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

Side by Side Diff: lib/MC/MCAssembler.cpp

Issue 11428170: Remove bundling from the MCAssembler interface (Closed) Base URL: http://git.chromium.org/native_client/pnacl-llvm.git@master
Patch Set: Created 8 years 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 | « include/llvm/MC/MCAssembler.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 //===- lib/MC/MCAssembler.cpp - Assembler Backend Implementation ----------===// 1 //===- lib/MC/MCAssembler.cpp - Assembler Backend Implementation ----------===//
2 // 2 //
3 // The LLVM Compiler Infrastructure 3 // The LLVM Compiler Infrastructure
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 #define DEBUG_TYPE "assembler" 10 #define DEBUG_TYPE "assembler"
(...skipping 475 matching lines...) Expand 10 before | Expand all | Expand 10 after
486 486
487 case MCFragment::FT_Dwarf: 487 case MCFragment::FT_Dwarf:
488 return cast<MCDwarfLineAddrFragment>(F).getContents().size(); 488 return cast<MCDwarfLineAddrFragment>(F).getContents().size();
489 case MCFragment::FT_DwarfFrame: 489 case MCFragment::FT_DwarfFrame:
490 return cast<MCDwarfCallFrameFragment>(F).getContents().size(); 490 return cast<MCDwarfCallFrameFragment>(F).getContents().size();
491 } 491 }
492 492
493 llvm_unreachable("invalid fragment kind"); 493 llvm_unreachable("invalid fragment kind");
494 } 494 }
495 495
496 void MCAsmLayout::LayoutFragment(MCFragment *F) {
497 MCFragment *Prev = F->getPrevNode();
498
499 // We should never try to recompute something which is up-to-date.
500 assert(!isFragmentUpToDate(F) && "Attempt to recompute up-to-date fragment!");
501 // We should never try to compute the fragment layout if it's predecessor
502 // isn't up-to-date.
503 assert((!Prev || isFragmentUpToDate(Prev)) &&
504 "Attempt to compute fragment before it's predecessor!");
505
506 ++stats::FragmentLayouts;
507
508 // Compute fragment offset and size.
509 uint64_t Offset = 0;
510 if (Prev)
511 Offset += Prev->Offset + getAssembler().computeFragmentSize(*this, *Prev);
512 // @LOCALMOD-BEGIN
513 F->BundlePadding = getAssembler().ComputeBundlePadding(*this, F, Offset);
514 Offset += F->BundlePadding;
515 // @LOCALMOD-END
516 F->Offset = Offset;
517 LastValidFragment[F->getParent()] = F;
518 }
519
520 // @LOCALMOD-BEGIN 496 // @LOCALMOD-BEGIN
497 namespace {
521 // Returns number of bytes of padding needed to align to bundle start. 498 // Returns number of bytes of padding needed to align to bundle start.
522 static uint64_t AddressToBundlePadding(uint64_t Address, uint64_t BundleMask) { 499 uint64_t AddressToBundlePadding(uint64_t Address, uint64_t BundleMask) {
eliben 2012/12/05 00:01:34 Why was static removed?
sehr 2012/12/05 00:11:05 Added back, per the coding conventions.
523 return (~Address + 1) & BundleMask; 500 return (~Address + 1) & BundleMask;
524 } 501 }
525 502
526 uint64_t MCAssembler::getBundleSize() const { 503 uint64_t ComputeNaClAlignMask(uint64_t NaClAlignSize) {
eliben 2012/12/05 00:01:34 static?
eliben 2012/12/05 00:01:34 why the change s/bundle/nacl/ here? Would we not w
sehr 2012/12/05 00:11:05 Done.
sehr 2012/12/05 00:11:05 Reverted, per your suggestion.
527 return getBackend().getBundleSize(); 504 uint64_t NaClAlignMask = NaClAlignSize - 1;
505 assert(NaClAlignSize != 0);
506 assert((NaClAlignSize & NaClAlignMask) == 0 &&
507 "Bundle size must be a power of 2!");
508 return NaClAlignMask;
528 } 509 }
529 510
530 uint64_t MCAssembler::getBundleMask() const { 511 unsigned ComputeGroupSize(MCFragment *F) {
531 uint64_t BundleSize = getBundleSize();
532 uint64_t BundleMask = BundleSize - 1;
533 assert(BundleSize != 0);
534 assert((BundleSize & BundleMask) == 0 &&
535 "Bundle size must be a power of 2!");
536 return BundleMask;
537 }
538
539 static unsigned ComputeGroupSize(MCFragment *F) {
540 if (!F->isBundleGroupStart()) { 512 if (!F->isBundleGroupStart()) {
541 return 0; 513 return 0;
542 } 514 }
543 515
544 unsigned GroupSize = 0; 516 unsigned GroupSize = 0;
545 MCFragment *Cur = F; 517 MCFragment *Cur = F;
546 while (Cur) { 518 while (Cur) {
547 switch (Cur->getKind()) { 519 switch (Cur->getKind()) {
548 default: llvm_unreachable("Unexpected fragment type in bundle!"); 520 default: llvm_unreachable("Unexpected fragment type in bundle!");
549 case MCFragment::FT_Align: 521 case MCFragment::FT_Align:
(...skipping 13 matching lines...) Expand all
563 GroupSize += cast<MCTinyFragment>(Cur)->getContents().size(); 535 GroupSize += cast<MCTinyFragment>(Cur)->getContents().size();
564 break; 536 break;
565 } 537 }
566 if (Cur->isBundleGroupEnd()) 538 if (Cur->isBundleGroupEnd())
567 break; 539 break;
568 Cur = Cur->getNextNode(); 540 Cur = Cur->getNextNode();
569 } 541 }
570 return GroupSize; 542 return GroupSize;
571 } 543 }
572 544
573 uint8_t MCAssembler::ComputeBundlePadding(const MCAsmLayout &Layout, 545 uint8_t ComputeBundlePadding(const MCAssembler &Asm,
574 MCFragment *F, 546 const MCAsmLayout &Layout,
575 uint64_t FragmentOffset) const { 547 MCFragment *F,
548 uint64_t FragmentOffset) {
576 if (!F->getParent()->isBundlingEnabled()) 549 if (!F->getParent()->isBundlingEnabled())
577 return 0; 550 return 0;
578 551
579 uint64_t BundleSize = getBundleSize(); 552 uint64_t BundleSize = Asm.getBackend().getBundleSize();
580 uint64_t BundleMask = getBundleMask(); 553 uint64_t BundleMask = ComputeNaClAlignMask(BundleSize);
581 unsigned GroupSize = ComputeGroupSize(F); 554 unsigned GroupSize = ComputeGroupSize(F);
582 555
583 if (GroupSize > BundleSize) { 556 if (GroupSize > BundleSize) {
584 // EmitFill creates large groups consisting of repeated single bytes. 557 // EmitFill creates large groups consisting of repeated single bytes.
585 // These should be safe at any alignment, and in any case we cannot 558 // These should be safe at any alignment, and in any case we cannot
586 // fix them up here. 559 // fix them up here.
587 return 0; 560 return 0;
588 } 561 }
589 562
590 uint64_t Padding = 0; 563 uint64_t Padding = 0;
591 uint64_t OffsetInBundle = FragmentOffset & BundleMask; 564 uint64_t OffsetInBundle = FragmentOffset & BundleMask;
592 565
593 if (OffsetInBundle + GroupSize > BundleSize || 566 if (OffsetInBundle + GroupSize > BundleSize ||
594 F->getBundleAlign() == MCFragment::BundleAlignStart) { 567 F->getBundleAlign() == MCFragment::BundleAlignStart) {
595 // If this group would cross the bundle boundary, or this group must be 568 // If this group would cross the bundle boundary, or this group must be
596 // aligned to the start of a bundle, then pad up to start of the next bundle 569 // aligned to the start of a bundle, then pad up to start of the next bundle
597 Padding += AddressToBundlePadding(OffsetInBundle, BundleMask); 570 Padding += AddressToBundlePadding(OffsetInBundle, BundleMask);
598 OffsetInBundle = 0; 571 OffsetInBundle = 0;
599 } 572 }
600 if (F->getBundleAlign() == MCFragment::BundleAlignEnd) { 573 if (F->getBundleAlign() == MCFragment::BundleAlignEnd) {
601 // Push to the end of the bundle 574 // Push to the end of the bundle
602 Padding += AddressToBundlePadding(OffsetInBundle + GroupSize, BundleMask); 575 Padding += AddressToBundlePadding(OffsetInBundle + GroupSize, BundleMask);
603 } 576 }
604 return Padding; 577 return Padding;
605 } 578 }
606 // @LOCALMOD-END
607 579
608
609
610
611 // @LOCALMOD-BEGIN
612 // Write out BundlePadding bytes in NOPs, being careful not to cross a bundle 580 // Write out BundlePadding bytes in NOPs, being careful not to cross a bundle
613 // boundary. 581 // boundary.
614 static void WriteBundlePadding(const MCAssembler &Asm, 582 void WriteBundlePadding(const MCAssembler &Asm,
615 const MCAsmLayout &Layout, 583 const MCAsmLayout &Layout,
616 uint64_t Offset, uint64_t TotalPadding, 584 uint64_t Offset, uint64_t TotalPadding,
617 MCObjectWriter *OW) { 585 MCObjectWriter *OW) {
618 uint64_t BundleSize = Asm.getBundleSize(); 586 uint64_t BundleSize = Asm.getBackend().getBundleSize();
619 uint64_t BundleMask = Asm.getBundleMask(); 587 uint64_t BundleMask = ComputeNaClAlignMask(BundleSize);
620 uint64_t PaddingLeft = TotalPadding; 588 uint64_t PaddingLeft = TotalPadding;
621 uint64_t StartPos = Offset; 589 uint64_t StartPos = Offset;
622 590
623 bool FirstWrite = true; 591 bool FirstWrite = true;
624 while (PaddingLeft > 0) { 592 while (PaddingLeft > 0) {
625 uint64_t NopsToWrite = 593 uint64_t NopsToWrite =
626 FirstWrite ? AddressToBundlePadding(StartPos, BundleMask) : 594 FirstWrite ? AddressToBundlePadding(StartPos, BundleMask) :
627 BundleSize; 595 BundleSize;
628 if (NopsToWrite > PaddingLeft) 596 if (NopsToWrite > PaddingLeft)
629 NopsToWrite = PaddingLeft; 597 NopsToWrite = PaddingLeft;
630 if (!Asm.getBackend().writeNopData(NopsToWrite, OW)) 598 if (!Asm.getBackend().writeNopData(NopsToWrite, OW))
631 report_fatal_error("unable to write nop sequence of " + 599 report_fatal_error("unable to write nop sequence of " +
632 Twine(NopsToWrite) + " bytes"); 600 Twine(NopsToWrite) + " bytes");
633 PaddingLeft -= NopsToWrite; 601 PaddingLeft -= NopsToWrite;
634 FirstWrite = false; 602 FirstWrite = false;
635 } 603 }
636 } 604 }
605
606 } // namespace
637 // @LOCALMOD-END 607 // @LOCALMOD-END
638 608
609 void MCAsmLayout::LayoutFragment(MCFragment *F) {
610 MCFragment *Prev = F->getPrevNode();
611
612 // We should never try to recompute something which is up-to-date.
613 assert(!isFragmentUpToDate(F) && "Attempt to recompute up-to-date fragment!");
614 // We should never try to compute the fragment layout if it's predecessor
615 // isn't up-to-date.
616 assert((!Prev || isFragmentUpToDate(Prev)) &&
617 "Attempt to compute fragment before it's predecessor!");
618
619 ++stats::FragmentLayouts;
620
621 // Compute fragment offset and size.
622 uint64_t Offset = 0;
623 if (Prev)
624 Offset += Prev->Offset + getAssembler().computeFragmentSize(*this, *Prev);
625 // @LOCALMOD-BEGIN
626 F->BundlePadding = ComputeBundlePadding(getAssembler(), *this, F, Offset);
627 Offset += F->BundlePadding;
628 // @LOCALMOD-END
629 F->Offset = Offset;
630 LastValidFragment[F->getParent()] = F;
631 }
632
633
639 /// WriteFragmentData - Write the \p F data to the output file. 634 /// WriteFragmentData - Write the \p F data to the output file.
640 static void WriteFragmentData(const MCAssembler &Asm, const MCAsmLayout &Layout, 635 static void WriteFragmentData(const MCAssembler &Asm, const MCAsmLayout &Layout,
641 const MCFragment &F) { 636 const MCFragment &F) {
642 MCObjectWriter *OW = &Asm.getWriter(); 637 MCObjectWriter *OW = &Asm.getWriter();
643 // @LOCALMOD-BEGIN 638 // @LOCALMOD-BEGIN
644 if (F.getParent()->isBundlingEnabled()) { 639 if (F.getParent()->isBundlingEnabled()) {
645 uint64_t BundlePadding = Layout.getFragmentPadding(&F); 640 uint64_t BundlePadding = Layout.getFragmentPadding(&F);
646 uint64_t PaddingOffset = Layout.getFragmentOffset(&F) - BundlePadding; 641 uint64_t PaddingOffset = Layout.getFragmentOffset(&F) - BundlePadding;
647 WriteBundlePadding(Asm, Layout, PaddingOffset, BundlePadding, OW); 642 WriteBundlePadding(Asm, Layout, PaddingOffset, BundlePadding, OW);
648 } 643 }
(...skipping 21 matching lines...) Expand all
670 Twine(AF.getValueSize()) + 665 Twine(AF.getValueSize()) +
671 "' is not a divisor of padding size '" + 666 "' is not a divisor of padding size '" +
672 Twine(FragmentSize) + "'"); 667 Twine(FragmentSize) + "'");
673 668
674 // See if we are aligning with nops, and if so do that first to try to fill 669 // See if we are aligning with nops, and if so do that first to try to fill
675 // the Count bytes. Then if that did not fill any bytes or there are any 670 // the Count bytes. Then if that did not fill any bytes or there are any
676 // bytes left to fill use the Value and ValueSize to fill the rest. 671 // bytes left to fill use the Value and ValueSize to fill the rest.
677 // If we are aligning with nops, ask that target to emit the right data. 672 // If we are aligning with nops, ask that target to emit the right data.
678 if (AF.hasEmitNops()) { 673 if (AF.hasEmitNops()) {
679 // @LOCALMOD-BEGIN 674 // @LOCALMOD-BEGIN
680 if (Asm.getBundleSize()) { 675 if (Asm.getBackend().getBundleSize()) {
681 WriteBundlePadding(Asm, Layout, 676 WriteBundlePadding(Asm, Layout,
682 Layout.getFragmentOffset(&F), 677 Layout.getFragmentOffset(&F),
683 FragmentSize, 678 FragmentSize,
684 OW); 679 OW);
685 break; 680 break;
686 } 681 }
687 // @LOCALMOD-END 682 // @LOCALMOD-END
688 683
689 if (!Asm.getBackend().writeNopData(Count, OW)) 684 if (!Asm.getBackend().writeNopData(Count, OW))
690 report_fatal_error("unable to write nop sequence of " + 685 report_fatal_error("unable to write nop sequence of " +
(...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after
1285 1280
1286 // anchors for MC*Fragment vtables 1281 // anchors for MC*Fragment vtables
1287 void MCDataFragment::anchor() { } 1282 void MCDataFragment::anchor() { }
1288 void MCInstFragment::anchor() { } 1283 void MCInstFragment::anchor() { }
1289 void MCAlignFragment::anchor() { } 1284 void MCAlignFragment::anchor() { }
1290 void MCFillFragment::anchor() { } 1285 void MCFillFragment::anchor() { }
1291 void MCOrgFragment::anchor() { } 1286 void MCOrgFragment::anchor() { }
1292 void MCLEBFragment::anchor() { } 1287 void MCLEBFragment::anchor() { }
1293 void MCDwarfLineAddrFragment::anchor() { } 1288 void MCDwarfLineAddrFragment::anchor() { }
1294 void MCDwarfCallFrameFragment::anchor() { } 1289 void MCDwarfCallFrameFragment::anchor() { }
OLDNEW
« no previous file with comments | « include/llvm/MC/MCAssembler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698