Index: include/llvm/MC/MCAssembler.h =================================================================== --- include/llvm/MC/MCAssembler.h +++ include/llvm/MC/MCAssembler.h @@ -1245,6 +1245,8 @@ FileNames.push_back(FileName); } + /// \brief Write the necessary bundle padding to the given object writer. + /// Expects a fragment \p F containing instructions and its size \p FSize. void writeFragmentPadding(const MCFragment &F, uint64_t FSize, MCObjectWriter *OW) const; @@ -1253,8 +1255,9 @@ void dump(); }; -/// \brief Compute the amount of padding required before this fragment to -/// obey bundling restrictions. +/// \brief Compute the amount of padding required before the fragment \p F to +/// obey bundling restrictions, where \p FOffset is the fragment's offset in +/// its section and \p FSize is the fragment's size. uint64_t computeBundlePadding(const MCAssembler &Assembler, const MCFragment *F, uint64_t FOffset, uint64_t FSize); Index: include/llvm/MC/MCELFStreamer.h =================================================================== --- include/llvm/MC/MCELFStreamer.h +++ include/llvm/MC/MCELFStreamer.h @@ -100,6 +100,7 @@ void fixSymbolsInTLSFixups(const MCExpr *expr); + /// \brief Merge the content of the fragment \p EF into the fragment \p DF. void mergeFragment(MCDataFragment *, MCEncodedFragmentWithFixups *); bool SeenIdent; @@ -114,6 +115,8 @@ SmallPtrSet BindingExplicitlySet; + /// BundleGroups - The stack of fragments holding the bundle-locked + /// instructions. llvm::SmallVector BundleGroups; }; Index: include/llvm/MC/MCObjectStreamer.h =================================================================== --- include/llvm/MC/MCObjectStreamer.h +++ include/llvm/MC/MCObjectStreamer.h @@ -83,10 +83,10 @@ bool changeSectionImpl(const MCSection *Section, const MCExpr *Subsection); - // If any labels have been emitted but not assigned fragments, ensure that - // they get assigned, either to F if possible or to a new data fragment. - // Optionally, it is also possible to provide an offset which will be set - // as a symbol offset within the fragment. + /// If any labels have been emitted but not assigned fragments, ensure that + /// they get assigned, either to F if possible or to a new data fragment. + /// Optionally, it is also possible to provide an offset \p FOffset, which + /// will be used as a symbol offset within the fragment. void flushPendingLabels(MCFragment *F, uint64_t FOffset = 0); public: Index: lib/MC/MCAssembler.cpp =================================================================== --- lib/MC/MCAssembler.cpp +++ lib/MC/MCAssembler.cpp @@ -636,9 +636,9 @@ // The fragment's offset will point to after the padding, and its computed // size won't include the padding. // - // When relax all flag is used, we optimize the bundling by writting the - // padding directly into fragments as the instructions are emitted in the - // streamer. + // 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()) { @@ -665,8 +665,6 @@ OW->WriteBytes(EF.getContents()); } -/// \brief Write the necessary bundle padding to the given object writer. -// Expects a fragment containing instructions and its size. void MCAssembler::writeFragmentPadding(const MCFragment &F, uint64_t FSize, MCObjectWriter *OW) const { // Should NOP padding be written out before this fragment? Index: lib/MC/MCELFStreamer.cpp =================================================================== --- lib/MC/MCELFStreamer.cpp +++ lib/MC/MCELFStreamer.cpp @@ -41,7 +41,6 @@ MCELFStreamer::~MCELFStreamer() { } -/// \brief Merge the content of the fragment \p EF into the fragment \p DF. void MCELFStreamer::mergeFragment(MCDataFragment *DF, MCEncodedFragmentWithFixups *EF) { MCAssembler &Assembler = getAssembler(); @@ -494,8 +493,13 @@ if (Assembler.isBundlingEnabled()) { MCSectionData *SD = getCurrentSectionData(); if (Assembler.getRelaxAll() && SD->isBundleLocked()) + // If the -mc-relax-all flag is used and we are bundle-locked, we re-use + // the current bundle group. DF = BundleGroups.back(); else if (Assembler.getRelaxAll() && !SD->isBundleLocked()) + // When not in a bundle-locked group and the -mc-relax-all flag is used, + // we create a new temporary fragment which will be later merged into + // the current fragment. DF = new MCDataFragment(); else if (SD->isBundleLocked() && !SD->isBundleGroupBeforeFirstInst()) // If we are bundle-locked, we re-use the current fragment. @@ -587,12 +591,17 @@ else if (SD->isBundleGroupBeforeFirstInst()) report_fatal_error("Empty bundle-locked group is forbidden"); + // When the -mc-relax-all flag is used, we emit instructions to fragments + // stored on a stack. When the bundle unlock is emited, we pop a fragment + // from the stack a merge it to the one below. if (getAssembler().getRelaxAll()) { assert(!BundleGroups.empty() && "There are no bundle groups"); MCDataFragment *DF = BundleGroups.back(); + // FIXME: Use BundleGroups to track the lock state instead. SD->setBundleLockState(MCSectionData::NotBundleLocked); + // FIXME: Use more separate fragments for nested groups. if (!SD->isBundleLocked()) { mergeFragment(getOrCreateDataFragment(), DF); BundleGroups.pop_back();