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

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: Eli's review changes 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
521 // Returns number of bytes of padding needed to align to bundle start. 497 // Returns number of bytes of padding needed to align to bundle start.
522 static uint64_t AddressToBundlePadding(uint64_t Address, uint64_t BundleMask) { 498 static uint64_t AddressToBundlePadding(uint64_t Address, uint64_t BundleMask) {
523 return (~Address + 1) & BundleMask; 499 return (~Address + 1) & BundleMask;
524 } 500 }
525 501
526 uint64_t MCAssembler::getBundleSize() const { 502 static uint64_t ComputeBundleMask(uint64_t BundleSize) {
527 return getBackend().getBundleSize();
528 }
529
530 uint64_t MCAssembler::getBundleMask() const {
531 uint64_t BundleSize = getBundleSize();
532 uint64_t BundleMask = BundleSize - 1; 503 uint64_t BundleMask = BundleSize - 1;
533 assert(BundleSize != 0); 504 assert(BundleSize != 0);
534 assert((BundleSize & BundleMask) == 0 && 505 assert((BundleSize & BundleMask) == 0 &&
535 "Bundle size must be a power of 2!"); 506 "Bundle size must be a power of 2!");
536 return BundleMask; 507 return BundleMask;
537 } 508 }
538 509
539 static unsigned ComputeGroupSize(MCFragment *F) { 510 static unsigned ComputeGroupSize(MCFragment *F) {
540 if (!F->isBundleGroupStart()) { 511 if (!F->isBundleGroupStart()) {
541 return 0; 512 return 0;
(...skipping 21 matching lines...) Expand all
563 GroupSize += cast<MCTinyFragment>(Cur)->getContents().size(); 534 GroupSize += cast<MCTinyFragment>(Cur)->getContents().size();
564 break; 535 break;
565 } 536 }
566 if (Cur->isBundleGroupEnd()) 537 if (Cur->isBundleGroupEnd())
567 break; 538 break;
568 Cur = Cur->getNextNode(); 539 Cur = Cur->getNextNode();
569 } 540 }
570 return GroupSize; 541 return GroupSize;
571 } 542 }
572 543
573 uint8_t MCAssembler::ComputeBundlePadding(const MCAsmLayout &Layout, 544 static uint8_t ComputeBundlePadding(const MCAssembler &Asm,
574 MCFragment *F, 545 const MCAsmLayout &Layout,
575 uint64_t FragmentOffset) const { 546 MCFragment *F,
547 uint64_t FragmentOffset) {
576 if (!F->getParent()->isBundlingEnabled()) 548 if (!F->getParent()->isBundlingEnabled())
577 return 0; 549 return 0;
578 550
579 uint64_t BundleSize = getBundleSize(); 551 uint64_t BundleSize = Asm.getBackend().getBundleSize();
580 uint64_t BundleMask = getBundleMask(); 552 uint64_t BundleMask = ComputeBundleMask(BundleSize);
581 unsigned GroupSize = ComputeGroupSize(F); 553 unsigned GroupSize = ComputeGroupSize(F);
582 554
583 if (GroupSize > BundleSize) { 555 if (GroupSize > BundleSize) {
584 // EmitFill creates large groups consisting of repeated single bytes. 556 // EmitFill creates large groups consisting of repeated single bytes.
585 // These should be safe at any alignment, and in any case we cannot 557 // These should be safe at any alignment, and in any case we cannot
586 // fix them up here. 558 // fix them up here.
587 return 0; 559 return 0;
588 } 560 }
589 561
590 uint64_t Padding = 0; 562 uint64_t Padding = 0;
591 uint64_t OffsetInBundle = FragmentOffset & BundleMask; 563 uint64_t OffsetInBundle = FragmentOffset & BundleMask;
592 564
593 if (OffsetInBundle + GroupSize > BundleSize || 565 if (OffsetInBundle + GroupSize > BundleSize ||
594 F->getBundleAlign() == MCFragment::BundleAlignStart) { 566 F->getBundleAlign() == MCFragment::BundleAlignStart) {
595 // If this group would cross the bundle boundary, or this group must be 567 // 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 568 // aligned to the start of a bundle, then pad up to start of the next bundle
597 Padding += AddressToBundlePadding(OffsetInBundle, BundleMask); 569 Padding += AddressToBundlePadding(OffsetInBundle, BundleMask);
598 OffsetInBundle = 0; 570 OffsetInBundle = 0;
599 } 571 }
600 if (F->getBundleAlign() == MCFragment::BundleAlignEnd) { 572 if (F->getBundleAlign() == MCFragment::BundleAlignEnd) {
601 // Push to the end of the bundle 573 // Push to the end of the bundle
602 Padding += AddressToBundlePadding(OffsetInBundle + GroupSize, BundleMask); 574 Padding += AddressToBundlePadding(OffsetInBundle + GroupSize, BundleMask);
603 } 575 }
604 return Padding; 576 return Padding;
605 } 577 }
606 // @LOCALMOD-END
607 578
608
609
610
611 // @LOCALMOD-BEGIN
612 // Write out BundlePadding bytes in NOPs, being careful not to cross a bundle 579 // Write out BundlePadding bytes in NOPs, being careful not to cross a bundle
613 // boundary. 580 // boundary.
614 static void WriteBundlePadding(const MCAssembler &Asm, 581 static void WriteBundlePadding(const MCAssembler &Asm,
615 const MCAsmLayout &Layout, 582 const MCAsmLayout &Layout,
616 uint64_t Offset, uint64_t TotalPadding, 583 uint64_t Offset, uint64_t TotalPadding,
617 MCObjectWriter *OW) { 584 MCObjectWriter *OW) {
618 uint64_t BundleSize = Asm.getBundleSize(); 585 uint64_t BundleSize = Asm.getBackend().getBundleSize();
619 uint64_t BundleMask = Asm.getBundleMask(); 586 uint64_t BundleMask = ComputeBundleMask(BundleSize);
620 uint64_t PaddingLeft = TotalPadding; 587 uint64_t PaddingLeft = TotalPadding;
621 uint64_t StartPos = Offset; 588 uint64_t StartPos = Offset;
622 589
623 bool FirstWrite = true; 590 bool FirstWrite = true;
624 while (PaddingLeft > 0) { 591 while (PaddingLeft > 0) {
625 uint64_t NopsToWrite = 592 uint64_t NopsToWrite =
626 FirstWrite ? AddressToBundlePadding(StartPos, BundleMask) : 593 FirstWrite ? AddressToBundlePadding(StartPos, BundleMask) :
627 BundleSize; 594 BundleSize;
628 if (NopsToWrite > PaddingLeft) 595 if (NopsToWrite > PaddingLeft)
629 NopsToWrite = PaddingLeft; 596 NopsToWrite = PaddingLeft;
630 if (!Asm.getBackend().writeNopData(NopsToWrite, OW)) 597 if (!Asm.getBackend().writeNopData(NopsToWrite, OW))
631 report_fatal_error("unable to write nop sequence of " + 598 report_fatal_error("unable to write nop sequence of " +
632 Twine(NopsToWrite) + " bytes"); 599 Twine(NopsToWrite) + " bytes");
633 PaddingLeft -= NopsToWrite; 600 PaddingLeft -= NopsToWrite;
634 FirstWrite = false; 601 FirstWrite = false;
635 } 602 }
636 } 603 }
637 // @LOCALMOD-END 604 // @LOCALMOD-END
638 605
606 void MCAsmLayout::LayoutFragment(MCFragment *F) {
607 MCFragment *Prev = F->getPrevNode();
608
609 // We should never try to recompute something which is up-to-date.
610 assert(!isFragmentUpToDate(F) && "Attempt to recompute up-to-date fragment!");
611 // We should never try to compute the fragment layout if it's predecessor
612 // isn't up-to-date.
613 assert((!Prev || isFragmentUpToDate(Prev)) &&
614 "Attempt to compute fragment before it's predecessor!");
615
616 ++stats::FragmentLayouts;
617
618 // Compute fragment offset and size.
619 uint64_t Offset = 0;
620 if (Prev)
621 Offset += Prev->Offset + getAssembler().computeFragmentSize(*this, *Prev);
622 // @LOCALMOD-BEGIN
623 F->BundlePadding = ComputeBundlePadding(getAssembler(), *this, F, Offset);
624 Offset += F->BundlePadding;
625 // @LOCALMOD-END
626 F->Offset = Offset;
627 LastValidFragment[F->getParent()] = F;
628 }
629
630
639 /// WriteFragmentData - Write the \p F data to the output file. 631 /// WriteFragmentData - Write the \p F data to the output file.
640 static void WriteFragmentData(const MCAssembler &Asm, const MCAsmLayout &Layout, 632 static void WriteFragmentData(const MCAssembler &Asm, const MCAsmLayout &Layout,
641 const MCFragment &F) { 633 const MCFragment &F) {
642 MCObjectWriter *OW = &Asm.getWriter(); 634 MCObjectWriter *OW = &Asm.getWriter();
643 // @LOCALMOD-BEGIN 635 // @LOCALMOD-BEGIN
644 if (F.getParent()->isBundlingEnabled()) { 636 if (F.getParent()->isBundlingEnabled()) {
645 uint64_t BundlePadding = Layout.getFragmentPadding(&F); 637 uint64_t BundlePadding = Layout.getFragmentPadding(&F);
646 uint64_t PaddingOffset = Layout.getFragmentOffset(&F) - BundlePadding; 638 uint64_t PaddingOffset = Layout.getFragmentOffset(&F) - BundlePadding;
647 WriteBundlePadding(Asm, Layout, PaddingOffset, BundlePadding, OW); 639 WriteBundlePadding(Asm, Layout, PaddingOffset, BundlePadding, OW);
648 } 640 }
(...skipping 21 matching lines...) Expand all
670 Twine(AF.getValueSize()) + 662 Twine(AF.getValueSize()) +
671 "' is not a divisor of padding size '" + 663 "' is not a divisor of padding size '" +
672 Twine(FragmentSize) + "'"); 664 Twine(FragmentSize) + "'");
673 665
674 // See if we are aligning with nops, and if so do that first to try to fill 666 // 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 667 // 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. 668 // 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. 669 // If we are aligning with nops, ask that target to emit the right data.
678 if (AF.hasEmitNops()) { 670 if (AF.hasEmitNops()) {
679 // @LOCALMOD-BEGIN 671 // @LOCALMOD-BEGIN
680 if (Asm.getBundleSize()) { 672 if (Asm.getBackend().getBundleSize()) {
681 WriteBundlePadding(Asm, Layout, 673 WriteBundlePadding(Asm, Layout,
682 Layout.getFragmentOffset(&F), 674 Layout.getFragmentOffset(&F),
683 FragmentSize, 675 FragmentSize,
684 OW); 676 OW);
685 break; 677 break;
686 } 678 }
687 // @LOCALMOD-END 679 // @LOCALMOD-END
688 680
689 if (!Asm.getBackend().writeNopData(Count, OW)) 681 if (!Asm.getBackend().writeNopData(Count, OW))
690 report_fatal_error("unable to write nop sequence of " + 682 report_fatal_error("unable to write nop sequence of " +
(...skipping 594 matching lines...) Expand 10 before | Expand all | Expand 10 after
1285 1277
1286 // anchors for MC*Fragment vtables 1278 // anchors for MC*Fragment vtables
1287 void MCDataFragment::anchor() { } 1279 void MCDataFragment::anchor() { }
1288 void MCInstFragment::anchor() { } 1280 void MCInstFragment::anchor() { }
1289 void MCAlignFragment::anchor() { } 1281 void MCAlignFragment::anchor() { }
1290 void MCFillFragment::anchor() { } 1282 void MCFillFragment::anchor() { }
1291 void MCOrgFragment::anchor() { } 1283 void MCOrgFragment::anchor() { }
1292 void MCLEBFragment::anchor() { } 1284 void MCLEBFragment::anchor() { }
1293 void MCDwarfLineAddrFragment::anchor() { } 1285 void MCDwarfLineAddrFragment::anchor() { }
1294 void MCDwarfCallFrameFragment::anchor() { } 1286 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