[llvm-commits] [llvm] r170718 - in /llvm/trunk: include/llvm/MC/MCAsmLayout.h include/llvm/MC/MCAssembler.h include/llvm/MC/MCELFStreamer.h include/llvm/MC/MCObjectStreamer.h include/llvm/MC/MCStreamer.h lib/MC/MCAsmStreamer.cpp lib/MC/MCAssembler.cpp lib/MC/MCELFStreamer.cpp lib/MC/MCNullStreamer.cpp lib/MC/MCObjectStreamer.cpp lib/MC/MCParser/AsmParser.cpp tools/lto/LTOModule.cpp
Jim Grosbach
grosbach at apple.com
Thu Dec 20 14:37:30 PST 2012
We're seeing this on some internal bots, too, when building clang itself with a just-built ToT clang.
Eli, do you think you'll be able to get this fixed soon, or should we revert temporarily to give you time to sort things out?
-Jim
On Dec 20, 2012, at 1:46 PM, Matt Beaumont-Gay <matthewbg at google.com> wrote:
> Hi Eli,
>
> Our internal buildbot with a freshly built Clang is reporting a number
> of "fatal error: error in backend: Fragment can't be larger than a
> bundle size" errors on various inputs, including a file in ICU. I
> don't have a small test case yet, but I wanted to give you a heads-up.
>
> On Thu, Dec 20, 2012 at 11:05 AM, Eli Bendersky <eliben at google.com> wrote:
>> Author: eliben
>> Date: Thu Dec 20 13:05:53 2012
>> New Revision: 170718
>>
>> URL: http://llvm.org/viewvc/llvm-project?rev=170718&view=rev
>> Log:
>> Aligned bundling support. Following the discussion here:
>> http://lists.cs.uiuc.edu/pipermail/llvmdev/2012-December/056754.html
>>
>> The proposal and implementation are fully documented here:
>> https://sites.google.com/a/chromium.org/dev/nativeclient/pnacl/aligned-bundling-support-in-llvm
>>
>> Tests will follow shortly.
>>
>> Modified:
>> llvm/trunk/include/llvm/MC/MCAsmLayout.h
>> llvm/trunk/include/llvm/MC/MCAssembler.h
>> llvm/trunk/include/llvm/MC/MCELFStreamer.h
>> llvm/trunk/include/llvm/MC/MCObjectStreamer.h
>> llvm/trunk/include/llvm/MC/MCStreamer.h
>> llvm/trunk/lib/MC/MCAsmStreamer.cpp
>> llvm/trunk/lib/MC/MCAssembler.cpp
>> llvm/trunk/lib/MC/MCELFStreamer.cpp
>> llvm/trunk/lib/MC/MCNullStreamer.cpp
>> llvm/trunk/lib/MC/MCObjectStreamer.cpp
>> llvm/trunk/lib/MC/MCParser/AsmParser.cpp
>> llvm/trunk/tools/lto/LTOModule.cpp
>>
>> Modified: llvm/trunk/include/llvm/MC/MCAsmLayout.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCAsmLayout.h?rev=170718&r1=170717&r2=170718&view=diff
>> ==============================================================================
>> --- llvm/trunk/include/llvm/MC/MCAsmLayout.h (original)
>> +++ llvm/trunk/include/llvm/MC/MCAsmLayout.h Thu Dec 20 13:05:53 2012
>> @@ -49,6 +49,11 @@
>> /// \brief Is the layout for this fragment valid?
>> bool isFragmentValid(const MCFragment *F) const;
>>
>> + /// \brief Compute the amount of padding required before this fragment to
>> + /// obey bundling restrictions.
>> + uint64_t computeBundlePadding(const MCFragment *F,
>> + uint64_t FOffset, uint64_t FSize);
>> +
>> public:
>> MCAsmLayout(MCAssembler &_Assembler);
>>
>>
>> Modified: llvm/trunk/include/llvm/MC/MCAssembler.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCAssembler.h?rev=170718&r1=170717&r2=170718&view=diff
>> ==============================================================================
>> --- llvm/trunk/include/llvm/MC/MCAssembler.h (original)
>> +++ llvm/trunk/include/llvm/MC/MCAssembler.h Thu Dec 20 13:05:53 2012
>> @@ -99,14 +99,35 @@
>> unsigned getLayoutOrder() const { return LayoutOrder; }
>> void setLayoutOrder(unsigned Value) { LayoutOrder = Value; }
>>
>> + /// \brief Does this fragment have instructions emitted into it? By default
>> + /// this is false, but specific fragment types may set it to true.
>> + virtual bool hasInstructions() const { return false; }
>> +
>> + /// \brief Get the padding size that must be inserted before this fragment.
>> + /// Used for bundling. By default, no padding is inserted.
>> + /// Note that padding size is restricted to 8 bits. This is an optimization
>> + /// to reduce the amount of space used for each fragment. In practice, larger
>> + /// padding should never be required.
>> + virtual uint8_t getBundlePadding() const {
>> + return 0;
>> + }
>> +
>> + /// \brief Set the padding size for this fragment. By default it's a no-op,
>> + /// and only some fragments have a meaningful implementation.
>> + virtual void setBundlePadding(uint8_t N) {
>> + }
>> +
>> void dump();
>> };
>>
>> class MCEncodedFragment : public MCFragment {
>> virtual void anchor();
>> +
>> + uint8_t BundlePadding;
>> public:
>> MCEncodedFragment(MCFragment::FragmentType FType, MCSectionData *SD = 0)
>> - : MCFragment(FType, SD) {
>> + : MCFragment(FType, SD), BundlePadding(0)
>> + {
>> }
>> virtual ~MCEncodedFragment();
>>
>> @@ -124,6 +145,14 @@
>> virtual fixup_iterator fixup_end() = 0;
>> virtual const_fixup_iterator fixup_end() const = 0;
>>
>> + virtual uint8_t getBundlePadding() const {
>> + return BundlePadding;
>> + }
>> +
>> + virtual void setBundlePadding(uint8_t N) {
>> + BundlePadding = N;
>> + }
>> +
>> static bool classof(const MCFragment *F) {
>> MCFragment::FragmentType Kind = F->getKind();
>> return Kind == MCFragment::FT_Inst || Kind == MCFragment::FT_Data;
>> @@ -132,14 +161,19 @@
>>
>> class MCDataFragment : public MCEncodedFragment {
>> virtual void anchor();
>> +
>> + /// \brief Does this fragment contain encoded instructions anywhere in it?
>> + bool HasInstructions;
>> +
>> SmallVector<char, 32> Contents;
>>
>> /// Fixups - The list of fixups in this fragment.
>> SmallVector<MCFixup, 4> Fixups;
>> -
>> public:
>> MCDataFragment(MCSectionData *SD = 0)
>> - : MCEncodedFragment(FT_Data, SD) {
>> + : MCEncodedFragment(FT_Data, SD),
>> + HasInstructions(false)
>> + {
>> }
>>
>> virtual SmallVectorImpl<char> &getContents() { return Contents; }
>> @@ -153,6 +187,9 @@
>> return Fixups;
>> }
>>
>> + virtual bool hasInstructions() const { return HasInstructions; }
>> + virtual void setHasInstructions(bool V) { HasInstructions = V; }
>> +
>> fixup_iterator fixup_begin() { return Fixups.begin(); }
>> const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
>>
>> @@ -196,6 +233,8 @@
>> return Fixups;
>> }
>>
>> + virtual bool hasInstructions() const { return true; }
>> +
>> fixup_iterator fixup_begin() { return Fixups.begin(); }
>> const_fixup_iterator fixup_begin() const { return Fixups.begin(); }
>>
>> @@ -450,6 +489,13 @@
>> /// Alignment - The maximum alignment seen in this section.
>> unsigned Alignment;
>>
>> + /// \brief We're currently inside a bundle-locked group.
>> + bool BundleLocked;
>> +
>> + /// \brief We've seen a bundle_lock directive but not its first instruction
>> + /// yet.
>> + bool BundleGroupBeforeFirstInst;
>> +
>> /// @name Assembler Backend Data
>> /// @{
>> //
>> @@ -502,6 +548,22 @@
>>
>> bool empty() const { return Fragments.empty(); }
>>
>> + bool isBundleLocked() const {
>> + return BundleLocked;
>> + }
>> +
>> + void setBundleLocked(bool IsLocked) {
>> + BundleLocked = IsLocked;
>> + }
>> +
>> + bool isBundleGroupBeforeFirstInst() const {
>> + return BundleGroupBeforeFirstInst;
>> + }
>> +
>> + void setBundleGroupBeforeFirstInst(bool IsFirst) {
>> + BundleGroupBeforeFirstInst = IsFirst;
>> + }
>> +
>> void dump();
>>
>> /// @}
>> @@ -707,6 +769,11 @@
>> // refactoring too.
>> SmallPtrSet<const MCSymbol*, 64> ThumbFuncs;
>>
>> + /// \brief The bundle alignment size currently set in the assembler.
>> + ///
>> + /// By default it's 0, which means bundling is disabled.
>> + unsigned BundleAlignSize;
>> +
>> unsigned RelaxAll : 1;
>> unsigned NoExecStack : 1;
>> unsigned SubsectionsViaSymbols : 1;
>> @@ -833,6 +900,20 @@
>> bool getNoExecStack() const { return NoExecStack; }
>> void setNoExecStack(bool Value) { NoExecStack = Value; }
>>
>> + bool isBundlingEnabled() const {
>> + return BundleAlignSize != 0;
>> + }
>> +
>> + unsigned getBundleAlignSize() const {
>> + return BundleAlignSize;
>> + }
>> +
>> + void setBundleAlignSize(unsigned Size) {
>> + assert((Size == 0 || !(Size & (Size - 1))) &&
>> + "Expect a power-of-two bundle align size");
>> + BundleAlignSize = Size;
>> + }
>> +
>> /// @name Section List Access
>> /// @{
>>
>>
>> Modified: llvm/trunk/include/llvm/MC/MCELFStreamer.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCELFStreamer.h?rev=170718&r1=170717&r2=170718&view=diff
>> ==============================================================================
>> --- llvm/trunk/include/llvm/MC/MCELFStreamer.h (original)
>> +++ llvm/trunk/include/llvm/MC/MCELFStreamer.h Thu Dec 20 13:05:53 2012
>> @@ -76,6 +76,8 @@
>>
>> virtual void EmitTCEntry(const MCSymbol &S);
>>
>> + virtual void EmitValueToAlignment(unsigned, int64_t, unsigned, unsigned);
>> +
>> virtual void FinishImpl();
>> /// @}
>>
>> @@ -83,6 +85,10 @@
>> virtual void EmitInstToFragment(const MCInst &Inst);
>> virtual void EmitInstToData(const MCInst &Inst);
>>
>> + virtual void EmitBundleAlignMode(unsigned AlignPow2);
>> + virtual void EmitBundleLock();
>> + virtual void EmitBundleUnlock();
>> +
>> void fixSymbolsInTLSFixups(const MCExpr *expr);
>>
>> struct LocalCommon {
>>
>> Modified: llvm/trunk/include/llvm/MC/MCObjectStreamer.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCObjectStreamer.h?rev=170718&r1=170717&r2=170718&view=diff
>> ==============================================================================
>> --- llvm/trunk/include/llvm/MC/MCObjectStreamer.h (original)
>> +++ llvm/trunk/include/llvm/MC/MCObjectStreamer.h Thu Dec 20 13:05:53 2012
>> @@ -78,7 +78,14 @@
>> virtual void EmitWeakReference(MCSymbol *Alias, const MCSymbol *Symbol);
>> virtual void ChangeSection(const MCSection *Section);
>> virtual void EmitInstruction(const MCInst &Inst);
>> +
>> + /// \brief Emit an instruction to a special fragment, because this instruction
>> + /// can change its size during relaxation.
>> virtual void EmitInstToFragment(const MCInst &Inst);
>> +
>> + virtual void EmitBundleAlignMode(unsigned AlignPow2);
>> + virtual void EmitBundleLock();
>> + virtual void EmitBundleUnlock();
>> virtual void EmitBytes(StringRef Data, unsigned AddrSpace);
>> virtual void EmitValueToAlignment(unsigned ByteAlignment,
>> int64_t Value = 0,
>>
>> Modified: llvm/trunk/include/llvm/MC/MCStreamer.h
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCStreamer.h?rev=170718&r1=170717&r2=170718&view=diff
>> ==============================================================================
>> --- llvm/trunk/include/llvm/MC/MCStreamer.h (original)
>> +++ llvm/trunk/include/llvm/MC/MCStreamer.h Thu Dec 20 13:05:53 2012
>> @@ -437,7 +437,6 @@
>> EmitFill(NumBytes, 0, AddrSpace);
>> }
>>
>> -
>> /// EmitValueToAlignment - Emit some number of copies of @p Value until
>> /// the byte alignment @p ByteAlignment is reached.
>> ///
>> @@ -557,6 +556,17 @@
>> /// section.
>> virtual void EmitInstruction(const MCInst &Inst) = 0;
>>
>> + /// \brief Set the bundle alignment mode from now on in the section.
>> + /// The argument is the power of 2 to which the alignment is set. The
>> + /// value 0 means turn the bundle alignment off.
>> + virtual void EmitBundleAlignMode(unsigned AlignPow2) = 0;
>> +
>> + /// \brief The following instructions are a bundle-locked group.
>> + virtual void EmitBundleLock() = 0;
>> +
>> + /// \brief Ends a bundle-locked group.
>> + virtual void EmitBundleUnlock() = 0;
>> +
>> /// EmitRawText - If this file is backed by a assembly streamer, this dumps
>> /// the specified string in the output .s file. This capability is
>> /// indicated by the hasRawTextSupport() predicate. By default this aborts.
>>
>> Modified: llvm/trunk/lib/MC/MCAsmStreamer.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAsmStreamer.cpp?rev=170718&r1=170717&r2=170718&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/MC/MCAsmStreamer.cpp (original)
>> +++ llvm/trunk/lib/MC/MCAsmStreamer.cpp Thu Dec 20 13:05:53 2012
>> @@ -259,6 +259,10 @@
>>
>> virtual void EmitInstruction(const MCInst &Inst);
>>
>> + virtual void EmitBundleAlignMode(unsigned AlignPow2);
>> + virtual void EmitBundleLock();
>> + virtual void EmitBundleUnlock();
>> +
>> /// EmitRawText - If this file is backed by an assembly streamer, this dumps
>> /// the specified string in the output .s file. This capability is
>> /// indicated by the hasRawTextSupport() predicate.
>> @@ -1361,6 +1365,21 @@
>> EmitEOL();
>> }
>>
>> +void MCAsmStreamer::EmitBundleAlignMode(unsigned AlignPow2) {
>> + OS << "\t.bundle_align_mode " << AlignPow2;
>> + EmitEOL();
>> +}
>> +
>> +void MCAsmStreamer::EmitBundleLock() {
>> + OS << "\t.bundle_lock";
>> + EmitEOL();
>> +}
>> +
>> +void MCAsmStreamer::EmitBundleUnlock() {
>> + OS << "\t.bundle_unlock";
>> + EmitEOL();
>> +}
>> +
>> /// EmitRawText - If this file is backed by an assembly streamer, this dumps
>> /// the specified string in the output .s file. This capability is
>> /// indicated by the hasRawTextSupport() predicate.
>>
>> Modified: llvm/trunk/lib/MC/MCAssembler.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAssembler.cpp?rev=170718&r1=170717&r2=170718&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/MC/MCAssembler.cpp (original)
>> +++ llvm/trunk/lib/MC/MCAssembler.cpp Thu Dec 20 13:05:53 2012
>> @@ -160,6 +160,22 @@
>> return getSectionAddressSize(SD);
>> }
>>
>> +uint64_t MCAsmLayout::computeBundlePadding(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");
>> + uint64_t BundleMask = BundleSize - 1;
>> + uint64_t OffsetInBundle = FOffset & BundleMask;
>> +
>> + // If the fragment would cross a bundle boundary, add enough padding until
>> + // the end of the current bundle.
>> + if (OffsetInBundle + FSize > BundleSize)
>> + return BundleSize - OffsetInBundle;
>> + else
>> + return 0;
>> +}
>> +
>> /* *** */
>>
>> MCFragment::MCFragment() : Kind(FragmentType(~0)) {
>> @@ -188,6 +204,7 @@
>> : Section(&_Section),
>> Ordinal(~UINT32_C(0)),
>> Alignment(1),
>> + BundleLocked(false), BundleGroupBeforeFirstInst(false),
>> HasInstructions(false)
>> {
>> if (A)
>> @@ -406,12 +423,42 @@
>> ++stats::FragmentLayouts;
>>
>> // Compute fragment offset and size.
>> - uint64_t Offset = 0;
>> if (Prev)
>> - Offset += Prev->Offset + getAssembler().computeFragmentSize(*this, *Prev);
>> -
>> - F->Offset = Offset;
>> + F->Offset = Prev->Offset + getAssembler().computeFragmentSize(*this, *Prev);
>> + else
>> + F->Offset = 0;
>> LastValidFragment[F->getParent()] = F;
>> +
>> + // If bundling is enabled and this fragment has instructions in it, it has to
>> + // obey the bundling restrictions. With padding, we'll have:
>> + //
>> + //
>> + // BundlePadding
>> + // |||
>> + // -------------------------------------
>> + // Prev |##########| F |
>> + // -------------------------------------
>> + // ^
>> + // |
>> + // F->Offset
>> + //
>> + // The fragment's offset will point to after the padding, and its computed
>> + // size won't include the padding.
>> + //
>> + if (Assembler.isBundlingEnabled() && F->hasInstructions()) {
>> + assert(isa<MCEncodedFragment>(F) &&
>> + "Only MCEncodedFragment implementations have instructions");
>> + uint64_t FSize = Assembler.computeFragmentSize(*this, *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);
>> + if (RequiredBundlePadding > UINT8_MAX)
>> + report_fatal_error("Padding cannot exceed 255 bytes");
>> + F->setBundlePadding(static_cast<uint8_t>(RequiredBundlePadding));
>> + F->Offset += RequiredBundlePadding;
>> + }
>> }
>>
>> /// \brief Write the contents of a fragment to the given object writer. Expects
>> @@ -425,6 +472,22 @@
>> static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout,
>> const MCFragment &F) {
>> MCObjectWriter *OW = &Asm.getWriter();
>> +
>> + // Should NOP padding be written out before this fragment?
>> + unsigned BundlePadding = F.getBundlePadding();
>> + if (BundlePadding > 0) {
>> + assert(Asm.isBundlingEnabled() &&
>> + "Writing bundle padding with disabled bundling");
>> + assert(F.hasInstructions() &&
>> + "Writing bundle padding for a fragment without instructions");
>> +
>> + if (!Asm.getBackend().writeNopData(BundlePadding, OW))
>> + report_fatal_error("unable to write NOP sequence of " +
>> + Twine(BundlePadding) + " bytes");
>> + }
>> +
>> + // This variable (and its dummy usage) is to participate in the assert at
>> + // the end of the function.
>> uint64_t Start = OW->getStream().tell();
>> (void) Start;
>>
>> @@ -529,7 +592,8 @@
>> }
>> }
>>
>> - assert(OW->getStream().tell() - Start == FragmentSize);
>> + assert(OW->getStream().tell() - Start == FragmentSize &&
>> + "The stream should advance by fragment size");
>> }
>>
>> void MCAssembler::writeSectionData(const MCSectionData *SD,
>> @@ -875,7 +939,9 @@
>> }
>>
>> OS << "<MCFragment " << (void*) this << " LayoutOrder:" << LayoutOrder
>> - << " Offset:" << Offset << ">";
>> + << " Offset:" << Offset
>> + << " HasInstructions:" << hasInstructions()
>> + << " BundlePadding:" << getBundlePadding() << ">";
>>
>> switch (getKind()) {
>> case MCFragment::FT_Align: {
>> @@ -957,7 +1023,8 @@
>> raw_ostream &OS = llvm::errs();
>>
>> OS << "<MCSectionData";
>> - OS << " Alignment:" << getAlignment() << " Fragments:[\n ";
>> + OS << " Alignment:" << getAlignment()
>> + << " Fragments:[\n ";
>> for (iterator it = begin(), ie = end(); it != ie; ++it) {
>> if (it != begin()) OS << ",\n ";
>> it->dump();
>>
>> Modified: llvm/trunk/lib/MC/MCELFStreamer.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCELFStreamer.cpp?rev=170718&r1=170717&r2=170718&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/MC/MCELFStreamer.cpp (original)
>> +++ llvm/trunk/lib/MC/MCELFStreamer.cpp Thu Dec 20 13:05:53 2012
>> @@ -105,6 +105,9 @@
>> }
>>
>> void MCELFStreamer::ChangeSection(const MCSection *Section) {
>> + MCSectionData *CurSection = getCurrentSectionData();
>> + if (CurSection && CurSection->isBundleLocked())
>> + report_fatal_error("Unterminated .bundle_lock when changing a section");
>> const MCSymbol *Grp = static_cast<const MCSectionELF *>(Section)->getGroup();
>> if (Grp)
>> getAssembler().getOrCreateSymbolData(*Grp);
>> @@ -262,10 +265,22 @@
>>
>> void MCELFStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size,
>> unsigned AddrSpace) {
>> + if (getCurrentSectionData()->isBundleLocked())
>> + report_fatal_error("Emitting values inside a locked bundle is forbidden");
>> fixSymbolsInTLSFixups(Value);
>> MCObjectStreamer::EmitValueImpl(Value, Size, AddrSpace);
>> }
>>
>> +void MCELFStreamer::EmitValueToAlignment(unsigned ByteAlignment,
>> + int64_t Value,
>> + unsigned ValueSize,
>> + unsigned MaxBytesToEmit) {
>> + if (getCurrentSectionData()->isBundleLocked())
>> + report_fatal_error("Emitting values inside a locked bundle is forbidden");
>> + MCObjectStreamer::EmitValueToAlignment(ByteAlignment, Value,
>> + ValueSize, MaxBytesToEmit);
>> +}
>> +
>>
>> // Add a symbol for the file name of this module. This is the second
>> // entry in the module's symbol table (the first being the null symbol).
>> @@ -335,25 +350,91 @@
>> }
>>
>> void MCELFStreamer::EmitInstToData(const MCInst &Inst) {
>> - MCDataFragment *DF = getOrCreateDataFragment();
>> -
>> + MCAssembler &Assembler = getAssembler();
>> SmallVector<MCFixup, 4> Fixups;
>> SmallString<256> Code;
>> raw_svector_ostream VecOS(Code);
>> - getAssembler().getEmitter().EncodeInstruction(Inst, VecOS, Fixups);
>> + Assembler.getEmitter().EncodeInstruction(Inst, VecOS, Fixups);
>> VecOS.flush();
>>
>> for (unsigned i = 0, e = Fixups.size(); i != e; ++i)
>> fixSymbolsInTLSFixups(Fixups[i].getValue());
>>
>> + // There are several possibilities here:
>> + //
>> + // If bundling is disabled, append the encoded instruction to the current data
>> + // fragment (or create a new such fragment if the current fragment is not a
>> + // data fragment).
>> + //
>> + // If bundling is enabled:
>> + // - If we're not in a bundle-locked group, emit the instruction into a data
>> + // fragment of its own.
>> + // - If we're in a bundle-locked group, append the instruction to the current
>> + // data fragment because we want all the instructions in a group to get into
>> + // the same fragment. Be careful not to do that for the first instruction in
>> + // the group, though.
>> + MCDataFragment *DF;
>> +
>> + if (Assembler.isBundlingEnabled()) {
>> + MCSectionData *SD = getCurrentSectionData();
>> + if (SD->isBundleLocked() && !SD->isBundleGroupBeforeFirstInst())
>> + DF = getOrCreateDataFragment();
>> + else
>> + DF = new MCDataFragment(SD);
>> +
>> + // We're now emitting an instruction in a bundle group, so this flag has
>> + // to be turned off.
>> + SD->setBundleGroupBeforeFirstInst(false);
>> + } else {
>> + DF = getOrCreateDataFragment();
>> + }
>> +
>> // Add the fixups and data.
>> for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
>> Fixups[i].setOffset(Fixups[i].getOffset() + DF->getContents().size());
>> DF->getFixups().push_back(Fixups[i]);
>> }
>> + DF->setHasInstructions(true);
>> DF->getContents().append(Code.begin(), Code.end());
>> }
>>
>> +void MCELFStreamer::EmitBundleAlignMode(unsigned AlignPow2) {
>> + assert(AlignPow2 <= 30 && "Invalid bundle alignment");
>> + MCAssembler &Assembler = getAssembler();
>> + if (Assembler.getBundleAlignSize() == 0 && AlignPow2 > 0)
>> + Assembler.setBundleAlignSize(1 << AlignPow2);
>> + else
>> + report_fatal_error(".bundle_align_mode should be only set once per file");
>> +}
>> +
>> +void MCELFStreamer::EmitBundleLock() {
>> + MCSectionData *SD = getCurrentSectionData();
>> +
>> + // Sanity checks
>> + //
>> + if (!getAssembler().isBundlingEnabled())
>> + report_fatal_error(".bundle_lock forbidden when bundling is disabled");
>> + else if (SD->isBundleLocked())
>> + report_fatal_error("Nesting of .bundle_lock is forbidden");
>> +
>> + SD->setBundleLocked(true);
>> + SD->setBundleGroupBeforeFirstInst(true);
>> +}
>> +
>> +void MCELFStreamer::EmitBundleUnlock() {
>> + MCSectionData *SD = getCurrentSectionData();
>> +
>> + // Sanity checks
>> + if (!getAssembler().isBundlingEnabled())
>> + report_fatal_error(".bundle_unlock forbidden when bundling is disabled");
>> + else if (!SD->isBundleLocked())
>> + report_fatal_error(".bundle_unlock without matching lock");
>> + else if (SD->isBundleGroupBeforeFirstInst())
>> + report_fatal_error("Empty bundle-locked group is forbidden");
>> +
>> + SD->setBundleLocked(false);
>> +}
>> +
>> void MCELFStreamer::FinishImpl() {
>> EmitFrames(true);
>>
>>
>> Modified: llvm/trunk/lib/MC/MCNullStreamer.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCNullStreamer.cpp?rev=170718&r1=170717&r2=170718&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/MC/MCNullStreamer.cpp (original)
>> +++ llvm/trunk/lib/MC/MCNullStreamer.cpp Thu Dec 20 13:05:53 2012
>> @@ -95,6 +95,10 @@
>> StringRef FileName) {}
>> virtual void EmitInstruction(const MCInst &Inst) {}
>>
>> + virtual void EmitBundleAlignMode(unsigned AlignPow2) {}
>> + virtual void EmitBundleLock() {}
>> + virtual void EmitBundleUnlock() {}
>> +
>> virtual void FinishImpl() {}
>>
>> virtual void EmitCFIEndProcImpl(MCDwarfFrameInfo &Frame) {
>>
>> Modified: llvm/trunk/lib/MC/MCObjectStreamer.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCObjectStreamer.cpp?rev=170718&r1=170717&r2=170718&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/MC/MCObjectStreamer.cpp (original)
>> +++ llvm/trunk/lib/MC/MCObjectStreamer.cpp Thu Dec 20 13:05:53 2012
>> @@ -180,21 +180,27 @@
>> if (Inst.getOperand(i).isExpr())
>> AddValueSymbols(Inst.getOperand(i).getExpr());
>>
>> - getCurrentSectionData()->setHasInstructions(true);
>> + MCSectionData *SD = getCurrentSectionData();
>> + SD->setHasInstructions(true);
>>
>> // Now that a machine instruction has been assembled into this section, make
>> // a line entry for any .loc directive that has been seen.
>> MCLineEntry::Make(this, getCurrentSection());
>>
>> // If this instruction doesn't need relaxation, just emit it as data.
>> - if (!getAssembler().getBackend().mayNeedRelaxation(Inst)) {
>> + MCAssembler &Assembler = getAssembler();
>> + if (!Assembler.getBackend().mayNeedRelaxation(Inst)) {
>> EmitInstToData(Inst);
>> return;
>> }
>>
>> - // Otherwise, if we are relaxing everything, relax the instruction as much as
>> - // possible and emit it as data.
>> - if (getAssembler().getRelaxAll()) {
>> + // Otherwise, relax and emit it as data if either:
>> + // - The RelaxAll flag was passed
>> + // - Bundling is enabled and this instruction is inside a bundle-locked
>> + // group. We want to emit all such instructions into the same data
>> + // fragment.
>> + if (Assembler.getRelaxAll() ||
>> + (Assembler.isBundlingEnabled() && SD->isBundleLocked())) {
>> MCInst Relaxed;
>> getAssembler().getBackend().relaxInstruction(Inst, Relaxed);
>> while (getAssembler().getBackend().mayNeedRelaxation(Relaxed))
>> @@ -208,6 +214,8 @@
>> }
>>
>> void MCObjectStreamer::EmitInstToFragment(const MCInst &Inst) {
>> + // Always create a new, separate fragment here, because its size can change
>> + // during relaxation.
>> MCInstFragment *IF = new MCInstFragment(Inst, getCurrentSectionData());
>>
>> SmallString<128> Code;
>> @@ -217,6 +225,21 @@
>> IF->getContents().append(Code.begin(), Code.end());
>> }
>>
>> +const char *BundlingNotImplementedMsg =
>> + "Aligned bundling is not implemented for this object format";
>> +
>> +void MCObjectStreamer::EmitBundleAlignMode(unsigned AlignPow2) {
>> + llvm_unreachable(BundlingNotImplementedMsg);
>> +}
>> +
>> +void MCObjectStreamer::EmitBundleLock() {
>> + llvm_unreachable(BundlingNotImplementedMsg);
>> +}
>> +
>> +void MCObjectStreamer::EmitBundleUnlock() {
>> + llvm_unreachable(BundlingNotImplementedMsg);
>> +}
>> +
>> void MCObjectStreamer::EmitDwarfAdvanceLineAddr(int64_t LineDelta,
>> const MCSymbol *LastLabel,
>> const MCSymbol *Label,
>>
>> Modified: llvm/trunk/lib/MC/MCParser/AsmParser.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCParser/AsmParser.cpp?rev=170718&r1=170717&r2=170718&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/MC/MCParser/AsmParser.cpp (original)
>> +++ llvm/trunk/lib/MC/MCParser/AsmParser.cpp Thu Dec 20 13:05:53 2012
>> @@ -305,6 +305,13 @@
>> // ".align{,32}", ".p2align{,w,l}"
>> bool ParseDirectiveAlign(bool IsPow2, unsigned ValueSize);
>>
>> + // ".bundle_align_mode"
>> + bool ParseDirectiveBundleAlignMode();
>> + // ".bundle_lock"
>> + bool ParseDirectiveBundleLock();
>> + // ".bundle_unlock"
>> + bool ParseDirectiveBundleUnlock();
>> +
>> /// ParseDirectiveSymbolAttribute - Parse a directive like ".globl" which
>> /// accepts a single symbol (which should be a label or an external).
>> bool ParseDirectiveSymbolAttribute(MCSymbolAttr Attr);
>> @@ -1304,6 +1311,13 @@
>> if (IDVal == ".p2alignl")
>> return ParseDirectiveAlign(/*IsPow2=*/true, /*ExprSize=*/4);
>>
>> + if (IDVal == ".bundle_align_mode")
>> + return ParseDirectiveBundleAlignMode();
>> + if (IDVal == ".bundle_lock")
>> + return ParseDirectiveBundleLock();
>> + if (IDVal == ".bundle_unlock")
>> + return ParseDirectiveBundleUnlock();
>> +
>> if (IDVal == ".org")
>> return ParseDirectiveOrg();
>>
>> @@ -2429,6 +2443,59 @@
>> return false;
>> }
>>
>> +
>> +/// ParseDirectiveBundleAlignMode
>> +/// ::= {.bundle_align_mode} expression
>> +bool AsmParser::ParseDirectiveBundleAlignMode() {
>> + CheckForValidSection();
>> +
>> + // Expect a single argument: an expression that evaluates to a constant
>> + // in the inclusive range 0-30.
>> + SMLoc ExprLoc = getLexer().getLoc();
>> + int64_t AlignSizePow2;
>> + if (ParseAbsoluteExpression(AlignSizePow2))
>> + return true;
>> + else if (getLexer().isNot(AsmToken::EndOfStatement))
>> + return TokError("unexpected token after expression in"
>> + " '.bundle_align_mode' directive");
>> + else if (AlignSizePow2 < 0 || AlignSizePow2 > 30)
>> + return Error(ExprLoc,
>> + "invalid bundle alignment size (expected between 0 and 30)");
>> +
>> + Lex();
>> +
>> + // Because of AlignSizePow2's verified range we can safely truncate it to
>> + // unsigned.
>> + getStreamer().EmitBundleAlignMode(static_cast<unsigned>(AlignSizePow2));
>> + return false;
>> +}
>> +
>> +/// ParseDirectiveBundleLock
>> +/// ::= {.bundle_lock}
>> +bool AsmParser::ParseDirectiveBundleLock() {
>> + CheckForValidSection();
>> +
>> + if (getLexer().isNot(AsmToken::EndOfStatement))
>> + return TokError("unexpected token in '.bundle_lock' directive");
>> + Lex();
>> +
>> + getStreamer().EmitBundleLock();
>> + return false;
>> +}
>> +
>> +/// ParseDirectiveBundleLock
>> +/// ::= {.bundle_lock}
>> +bool AsmParser::ParseDirectiveBundleUnlock() {
>> + CheckForValidSection();
>> +
>> + if (getLexer().isNot(AsmToken::EndOfStatement))
>> + return TokError("unexpected token in '.bundle_unlock' directive");
>> + Lex();
>> +
>> + getStreamer().EmitBundleUnlock();
>> + return false;
>> +}
>> +
>> /// ParseDirectiveSymbolAttribute
>> /// ::= { ".globl", ".weak", ... } [ identifier ( , identifier )* ]
>> bool AsmParser::ParseDirectiveSymbolAttribute(MCSymbolAttr Attr) {
>>
>> Modified: llvm/trunk/tools/lto/LTOModule.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/lto/LTOModule.cpp?rev=170718&r1=170717&r2=170718&view=diff
>> ==============================================================================
>> --- llvm/trunk/tools/lto/LTOModule.cpp (original)
>> +++ llvm/trunk/tools/lto/LTOModule.cpp Thu Dec 20 13:05:53 2012
>> @@ -765,6 +765,10 @@
>> markDefined(*Symbol);
>> }
>>
>> + virtual void EmitBundleAlignMode(unsigned AlignPow2) {}
>> + virtual void EmitBundleLock() {}
>> + virtual void EmitBundleUnlock() {}
>> +
>> // Noop calls.
>> virtual void ChangeSection(const MCSection *Section) {}
>> virtual void InitSections() {}
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list