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

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

Issue 1133723005: Cherry-pick r234714: [MC] Write padding into fragments when -mc-relax-all flag is used (Closed) Base URL: http://git.chromium.org/native_client/pnacl-llvm.git@master
Patch Set: Rebase Created 5 years, 7 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
« no previous file with comments | « include/llvm/MC/MCObjectStreamer.h ('k') | lib/MC/MCELFStreamer.cpp » ('j') | 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 #include "llvm/MC/MCAssembler.h" 10 #include "llvm/MC/MCAssembler.h"
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 212
213 uint64_t MCAsmLayout::getSectionFileSize(const MCSectionData *SD) const { 213 uint64_t MCAsmLayout::getSectionFileSize(const MCSectionData *SD) const {
214 // Virtual sections have no file size. 214 // Virtual sections have no file size.
215 if (SD->getSection().isVirtualSection()) 215 if (SD->getSection().isVirtualSection())
216 return 0; 216 return 0;
217 217
218 // Otherwise, the file size is the same as the address space size. 218 // Otherwise, the file size is the same as the address space size.
219 return getSectionAddressSize(SD); 219 return getSectionAddressSize(SD);
220 } 220 }
221 221
222 uint64_t MCAsmLayout::computeBundlePadding(const MCFragment *F, 222 uint64_t llvm::computeBundlePadding(const MCAssembler &Assembler,
223 uint64_t FOffset, uint64_t FSize) { 223 const MCFragment *F,
224 uint64_t FOffset, uint64_t FSize) {
224 uint64_t BundleSize = Assembler.getBundleAlignSize(); 225 uint64_t BundleSize = Assembler.getBundleAlignSize();
225 assert(BundleSize > 0 && 226 assert(BundleSize > 0 &&
226 "computeBundlePadding should only be called if bundling is enabled"); 227 "computeBundlePadding should only be called if bundling is enabled");
227 uint64_t BundleMask = BundleSize - 1; 228 uint64_t BundleMask = BundleSize - 1;
228 uint64_t OffsetInBundle = FOffset & BundleMask; 229 uint64_t OffsetInBundle = FOffset & BundleMask;
229 uint64_t EndOfFragment = OffsetInBundle + FSize; 230 uint64_t EndOfFragment = OffsetInBundle + FSize;
230 231
231 // There are two kinds of bundling restrictions: 232 // There are two kinds of bundling restrictions:
232 // 233 //
233 // 1) For alignToBundleEnd(), add padding to ensure that the fragment will 234 // 1) For alignToBundleEnd(), add padding to ensure that the fragment will
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
329 else 330 else
330 IP = MI->second; 331 IP = MI->second;
331 if (!ExactMatch && Subsection != 0) { 332 if (!ExactMatch && Subsection != 0) {
332 // The GNU as documentation claims that subsections have an alignment of 4, 333 // The GNU as documentation claims that subsections have an alignment of 4,
333 // although this appears not to be the case. 334 // although this appears not to be the case.
334 MCFragment *F = new MCDataFragment(); 335 MCFragment *F = new MCDataFragment();
335 SubsectionFragmentMap.insert(MI, std::make_pair(Subsection, F)); 336 SubsectionFragmentMap.insert(MI, std::make_pair(Subsection, F));
336 getFragmentList().insert(IP, F); 337 getFragmentList().insert(IP, F);
337 F->setParent(this); 338 F->setParent(this);
338 } 339 }
340
339 return IP; 341 return IP;
340 } 342 }
341 343
342 void MCSectionData::setBundleLockState(BundleLockStateType NewState) { 344 void MCSectionData::setBundleLockState(BundleLockStateType NewState) {
343 if (NewState == NotBundleLocked) { 345 if (NewState == NotBundleLocked) {
344 if (BundleLockNestingDepth == 0) { 346 if (BundleLockNestingDepth == 0) {
345 report_fatal_error("Mismatched bundle_lock/unlock directives"); 347 report_fatal_error("Mismatched bundle_lock/unlock directives");
346 } 348 }
347 if (--BundleLockNestingDepth == 0) { 349 if (--BundleLockNestingDepth == 0) {
348 BundleLockState = NotBundleLocked; 350 BundleLockState = NotBundleLocked;
(...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after
631 // ------------------------------------- 633 // -------------------------------------
632 // Prev |##########| F | 634 // Prev |##########| F |
633 // ------------------------------------- 635 // -------------------------------------
634 // ^ 636 // ^
635 // | 637 // |
636 // F->Offset 638 // F->Offset
637 // 639 //
638 // The fragment's offset will point to after the padding, and its computed 640 // The fragment's offset will point to after the padding, and its computed
639 // size won't include the padding. 641 // size won't include the padding.
640 // 642 //
641 if (Assembler.isBundlingEnabled() && F->hasInstructions()) { 643 // When the -mc-relax-all flag is used, we optimize bundling by writting the
644 // bundle padding directly into fragments when the instructions are emitted
645 // inside the streamer.
646 //
647 if (Assembler.isBundlingEnabled() && !Assembler.getRelaxAll() &&
648 F->hasInstructions()) {
642 assert(isa<MCEncodedFragment>(F) && 649 assert(isa<MCEncodedFragment>(F) &&
643 "Only MCEncodedFragment implementations have instructions"); 650 "Only MCEncodedFragment implementations have instructions");
644 uint64_t FSize = Assembler.computeFragmentSize(*this, *F); 651 uint64_t FSize = Assembler.computeFragmentSize(*this, *F);
645 652
646 if (FSize > Assembler.getBundleAlignSize()) 653 if (FSize > Assembler.getBundleAlignSize())
647 report_fatal_error("Fragment can't be larger than a bundle size"); 654 report_fatal_error("Fragment can't be larger than a bundle size");
648 655
649 uint64_t RequiredBundlePadding = computeBundlePadding(F, F->Offset, FSize); 656 uint64_t RequiredBundlePadding = computeBundlePadding(Assembler, F,
657 F->Offset, FSize);
650 if (RequiredBundlePadding > UINT8_MAX) 658 if (RequiredBundlePadding > UINT8_MAX)
651 report_fatal_error("Padding cannot exceed 255 bytes"); 659 report_fatal_error("Padding cannot exceed 255 bytes");
652 F->setBundlePadding(static_cast<uint8_t>(RequiredBundlePadding)); 660 F->setBundlePadding(static_cast<uint8_t>(RequiredBundlePadding));
653 F->Offset += RequiredBundlePadding; 661 F->Offset += RequiredBundlePadding;
654 } 662 }
655 } 663 }
656 664
657 /// \brief Write the contents of a fragment to the given object writer. Expects 665 /// \brief Write the contents of a fragment to the given object writer. Expects
658 /// a MCEncodedFragment. 666 /// a MCEncodedFragment.
659 static void writeFragmentContents(const MCFragment &F, MCObjectWriter *OW) { 667 static void writeFragmentContents(const MCFragment &F, MCObjectWriter *OW) {
660 const MCEncodedFragment &EF = cast<MCEncodedFragment>(F); 668 const MCEncodedFragment &EF = cast<MCEncodedFragment>(F);
661 OW->WriteBytes(EF.getContents()); 669 OW->WriteBytes(EF.getContents());
662 } 670 }
663 671
664 /// \brief Write the fragment \p F to the output file. 672 void MCAssembler::writeFragmentPadding(const MCFragment &F, uint64_t FSize,
665 static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout, 673 MCObjectWriter *OW) const {
666 const MCFragment &F) {
667 MCObjectWriter *OW = &Asm.getWriter();
668
669 // FIXME: Embed in fragments instead?
670 uint64_t FragmentSize = Asm.computeFragmentSize(Layout, F);
671
672 // Should NOP padding be written out before this fragment? 674 // Should NOP padding be written out before this fragment?
673 unsigned BundlePadding = F.getBundlePadding(); 675 unsigned BundlePadding = F.getBundlePadding();
674 if (BundlePadding > 0) { 676 if (BundlePadding > 0) {
675 assert(Asm.isBundlingEnabled() && 677 assert(isBundlingEnabled() &&
676 "Writing bundle padding with disabled bundling"); 678 "Writing bundle padding with disabled bundling");
677 assert(F.hasInstructions() && 679 assert(F.hasInstructions() &&
678 "Writing bundle padding for a fragment without instructions"); 680 "Writing bundle padding for a fragment without instructions");
679 681
680 unsigned TotalLength = BundlePadding + static_cast<unsigned>(FragmentSize); 682 unsigned TotalLength = BundlePadding + static_cast<unsigned>(FSize);
681 if (F.alignToBundleEnd() && TotalLength > Asm.getBundleAlignSize()) { 683 if (F.alignToBundleEnd() && TotalLength > getBundleAlignSize()) {
682 // If the padding itself crosses a bundle boundary, it must be emitted 684 // If the padding itself crosses a bundle boundary, it must be emitted
683 // in 2 pieces, since even nop instructions must not cross boundaries. 685 // in 2 pieces, since even nop instructions must not cross boundaries.
684 // v--------------v <- BundleAlignSize 686 // v--------------v <- BundleAlignSize
685 // v---------v <- BundlePadding 687 // v---------v <- BundlePadding
686 // ---------------------------- 688 // ----------------------------
687 // | Prev |####|####| F | 689 // | Prev |####|####| F |
688 // ---------------------------- 690 // ----------------------------
689 // ^-------------------^ <- TotalLength 691 // ^-------------------^ <- TotalLength
690 unsigned DistanceToBoundary = TotalLength - Asm.getBundleAlignSize(); 692 unsigned DistanceToBoundary = TotalLength - getBundleAlignSize();
691 if (!Asm.getBackend().writeNopData(DistanceToBoundary, OW)) 693 if (!getBackend().writeNopData(DistanceToBoundary, OW))
692 report_fatal_error("unable to write NOP sequence of " + 694 report_fatal_error("unable to write NOP sequence of " +
693 Twine(DistanceToBoundary) + " bytes"); 695 Twine(DistanceToBoundary) + " bytes");
694 BundlePadding -= DistanceToBoundary; 696 BundlePadding -= DistanceToBoundary;
695 } 697 }
696 if (!Asm.getBackend().writeNopData(BundlePadding, OW)) 698 if (!getBackend().writeNopData(BundlePadding, OW))
697 report_fatal_error("unable to write NOP sequence of " + 699 report_fatal_error("unable to write NOP sequence of " +
698 Twine(BundlePadding) + " bytes"); 700 Twine(BundlePadding) + " bytes");
699 } 701 }
702 }
703
704 /// \brief Write the fragment \p F to the output file.
705 static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout,
706 const MCFragment &F) {
707 MCObjectWriter *OW = &Asm.getWriter();
708
709 // FIXME: Embed in fragments instead?
710 uint64_t FragmentSize = Asm.computeFragmentSize(Layout, F);
711
712 Asm.writeFragmentPadding(F, FragmentSize, OW);
700 713
701 // This variable (and its dummy usage) is to participate in the assert at 714 // This variable (and its dummy usage) is to participate in the assert at
702 // the end of the function. 715 // the end of the function.
703 uint64_t Start = OW->getStream().tell(); 716 uint64_t Start = OW->getStream().tell();
704 (void) Start; 717 (void) Start;
705 718
706 ++stats::EmittedFragments; 719 ++stats::EmittedFragments;
707 720
708 switch (F.getKind()) { 721 switch (F.getKind()) {
709 case MCFragment::FT_Align: { 722 case MCFragment::FT_Align: {
(...skipping 599 matching lines...) Expand 10 before | Expand all | Expand 10 after
1309 void MCEncodedFragmentWithFixups::anchor() { } 1322 void MCEncodedFragmentWithFixups::anchor() { }
1310 void MCDataFragment::anchor() { } 1323 void MCDataFragment::anchor() { }
1311 void MCCompactEncodedInstFragment::anchor() { } 1324 void MCCompactEncodedInstFragment::anchor() { }
1312 void MCRelaxableFragment::anchor() { } 1325 void MCRelaxableFragment::anchor() { }
1313 void MCAlignFragment::anchor() { } 1326 void MCAlignFragment::anchor() { }
1314 void MCFillFragment::anchor() { } 1327 void MCFillFragment::anchor() { }
1315 void MCOrgFragment::anchor() { } 1328 void MCOrgFragment::anchor() { }
1316 void MCLEBFragment::anchor() { } 1329 void MCLEBFragment::anchor() { }
1317 void MCDwarfLineAddrFragment::anchor() { } 1330 void MCDwarfLineAddrFragment::anchor() { }
1318 void MCDwarfCallFrameFragment::anchor() { } 1331 void MCDwarfCallFrameFragment::anchor() { }
OLDNEW
« no previous file with comments | « include/llvm/MC/MCObjectStreamer.h ('k') | lib/MC/MCELFStreamer.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698