| Index: lib/MC/MCAssembler.cpp
|
| diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp
|
| index b8860dfd02a1d479b7ce80535fe8906a1cb0d2af..8008b558b8392a2a54acedc212ffe5ae1ee92c33 100644
|
| --- a/lib/MC/MCAssembler.cpp
|
| +++ b/lib/MC/MCAssembler.cpp
|
| @@ -219,8 +219,9 @@ uint64_t MCAsmLayout::getSectionFileSize(const MCSectionData *SD) const {
|
| return getSectionAddressSize(SD);
|
| }
|
|
|
| -uint64_t MCAsmLayout::computeBundlePadding(const MCFragment *F,
|
| - uint64_t FOffset, uint64_t FSize) {
|
| +uint64_t llvm::computeBundlePadding(const MCAssembler &Assembler,
|
| + const MCFragment *F,
|
| + uint64_t FOffset, uint64_t FSize) {
|
| uint64_t BundleSize = Assembler.getBundleAlignSize();
|
| assert(BundleSize > 0 &&
|
| "computeBundlePadding should only be called if bundling is enabled");
|
| @@ -336,6 +337,7 @@ MCSectionData::getSubsectionInsertionPoint(unsigned Subsection) {
|
| getFragmentList().insert(IP, F);
|
| F->setParent(this);
|
| }
|
| +
|
| return IP;
|
| }
|
|
|
| @@ -638,7 +640,12 @@ void MCAsmLayout::layoutFragment(MCFragment *F) {
|
| // The fragment's offset will point to after the padding, and its computed
|
| // size won't include the padding.
|
| //
|
| - if (Assembler.isBundlingEnabled() && F->hasInstructions()) {
|
| + // When the -mc-relax-all flag is used, we optimize bundling by writting the
|
| + // bundle padding directly into fragments when the instructions are emitted
|
| + // inside the streamer.
|
| + //
|
| + if (Assembler.isBundlingEnabled() && !Assembler.getRelaxAll() &&
|
| + F->hasInstructions()) {
|
| assert(isa<MCEncodedFragment>(F) &&
|
| "Only MCEncodedFragment implementations have instructions");
|
| uint64_t FSize = Assembler.computeFragmentSize(*this, *F);
|
| @@ -646,7 +653,8 @@ void MCAsmLayout::layoutFragment(MCFragment *F) {
|
| if (FSize > Assembler.getBundleAlignSize())
|
| report_fatal_error("Fragment can't be larger than a bundle size");
|
|
|
| - uint64_t RequiredBundlePadding = computeBundlePadding(F, F->Offset, FSize);
|
| + uint64_t RequiredBundlePadding = computeBundlePadding(Assembler, F,
|
| + F->Offset, FSize);
|
| if (RequiredBundlePadding > UINT8_MAX)
|
| report_fatal_error("Padding cannot exceed 255 bytes");
|
| F->setBundlePadding(static_cast<uint8_t>(RequiredBundlePadding));
|
| @@ -661,24 +669,18 @@ static void writeFragmentContents(const MCFragment &F, MCObjectWriter *OW) {
|
| OW->WriteBytes(EF.getContents());
|
| }
|
|
|
| -/// \brief Write the fragment \p F to the output file.
|
| -static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout,
|
| - const MCFragment &F) {
|
| - MCObjectWriter *OW = &Asm.getWriter();
|
| -
|
| - // FIXME: Embed in fragments instead?
|
| - uint64_t FragmentSize = Asm.computeFragmentSize(Layout, F);
|
| -
|
| +void MCAssembler::writeFragmentPadding(const MCFragment &F, uint64_t FSize,
|
| + MCObjectWriter *OW) const {
|
| // Should NOP padding be written out before this fragment?
|
| unsigned BundlePadding = F.getBundlePadding();
|
| if (BundlePadding > 0) {
|
| - assert(Asm.isBundlingEnabled() &&
|
| + assert(isBundlingEnabled() &&
|
| "Writing bundle padding with disabled bundling");
|
| assert(F.hasInstructions() &&
|
| "Writing bundle padding for a fragment without instructions");
|
|
|
| - unsigned TotalLength = BundlePadding + static_cast<unsigned>(FragmentSize);
|
| - if (F.alignToBundleEnd() && TotalLength > Asm.getBundleAlignSize()) {
|
| + unsigned TotalLength = BundlePadding + static_cast<unsigned>(FSize);
|
| + if (F.alignToBundleEnd() && TotalLength > getBundleAlignSize()) {
|
| // If the padding itself crosses a bundle boundary, it must be emitted
|
| // in 2 pieces, since even nop instructions must not cross boundaries.
|
| // v--------------v <- BundleAlignSize
|
| @@ -687,16 +689,27 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout,
|
| // | Prev |####|####| F |
|
| // ----------------------------
|
| // ^-------------------^ <- TotalLength
|
| - unsigned DistanceToBoundary = TotalLength - Asm.getBundleAlignSize();
|
| - if (!Asm.getBackend().writeNopData(DistanceToBoundary, OW))
|
| + unsigned DistanceToBoundary = TotalLength - getBundleAlignSize();
|
| + if (!getBackend().writeNopData(DistanceToBoundary, OW))
|
| report_fatal_error("unable to write NOP sequence of " +
|
| Twine(DistanceToBoundary) + " bytes");
|
| BundlePadding -= DistanceToBoundary;
|
| }
|
| - if (!Asm.getBackend().writeNopData(BundlePadding, OW))
|
| + if (!getBackend().writeNopData(BundlePadding, OW))
|
| report_fatal_error("unable to write NOP sequence of " +
|
| Twine(BundlePadding) + " bytes");
|
| }
|
| +}
|
| +
|
| +/// \brief Write the fragment \p F to the output file.
|
| +static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout,
|
| + const MCFragment &F) {
|
| + MCObjectWriter *OW = &Asm.getWriter();
|
| +
|
| + // FIXME: Embed in fragments instead?
|
| + uint64_t FragmentSize = Asm.computeFragmentSize(Layout, F);
|
| +
|
| + Asm.writeFragmentPadding(F, FragmentSize, OW);
|
|
|
| // This variable (and its dummy usage) is to participate in the assert at
|
| // the end of the function.
|
|
|