Index: llvm/trunk/include/llvm/MC/MCAssembler.h =================================================================== --- llvm/trunk/include/llvm/MC/MCAssembler.h +++ llvm/trunk/include/llvm/MC/MCAssembler.h @@ -442,7 +442,7 @@ /// Write the necessary bundle padding to \p OS. /// Expects a fragment \p F containing instructions and its size \p FSize. - void writeFragmentPadding(raw_ostream &OS, const MCFragment &F, + void writeFragmentPadding(raw_ostream &OS, const MCEncodedFragment &F, uint64_t FSize) const; /// @} @@ -453,8 +453,9 @@ /// 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); +uint64_t computeBundlePadding(const MCAssembler &Assembler, + const MCEncodedFragment *F, uint64_t FOffset, + uint64_t FSize); } // end namespace llvm Index: llvm/trunk/include/llvm/MC/MCFragment.h =================================================================== --- llvm/trunk/include/llvm/MC/MCFragment.h +++ llvm/trunk/include/llvm/MC/MCFragment.h @@ -56,11 +56,6 @@ bool HasInstructions; private: - /// Should this fragment be aligned to the end of a bundle? - bool AlignToBundleEnd; - - uint8_t BundlePadding; - /// LayoutOrder - The layout order of this fragment. unsigned LayoutOrder; @@ -84,7 +79,7 @@ protected: MCFragment(FragmentType Kind, bool HasInstructions, - uint8_t BundlePadding, MCSection *Parent = nullptr); + MCSection *Parent = nullptr); ~MCFragment(); @@ -114,21 +109,6 @@ /// this is false, but specific fragment types may set it to true. bool hasInstructions() const { return HasInstructions; } - /// Should this fragment be placed at the end of an aligned bundle? - bool alignToBundleEnd() const { return AlignToBundleEnd; } - void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; } - - /// 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. - uint8_t getBundlePadding() const { return BundlePadding; } - - /// Set the padding size for this fragment. By default it's a no-op, - /// and only some fragments have a meaningful implementation. - void setBundlePadding(uint8_t N) { BundlePadding = N; } - /// Return true if given frgment has FT_Dummy type. bool isDummy() const { return Kind == FT_Dummy; } @@ -137,8 +117,7 @@ class MCDummyFragment : public MCFragment { public: - explicit MCDummyFragment(MCSection *Sec) - : MCFragment(FT_Dummy, false, 0, Sec) {} + explicit MCDummyFragment(MCSection *Sec) : MCFragment(FT_Dummy, false, Sec) {} static bool classof(const MCFragment *F) { return F->getKind() == FT_Dummy; } }; @@ -147,10 +126,19 @@ /// data. /// class MCEncodedFragment : public MCFragment { + /// Should this fragment be aligned to the end of a bundle? + bool AlignToBundleEnd = false; + + uint8_t BundlePadding = 0; + protected: MCEncodedFragment(MCFragment::FragmentType FType, bool HasInstructions, MCSection *Sec) - : MCFragment(FType, HasInstructions, 0, Sec) {} + : MCFragment(FType, HasInstructions, Sec) {} + + /// STI - The MCSubtargetInfo in effect when the instruction was encoded. + /// must be non-null for instructions. + const MCSubtargetInfo *STI = nullptr; public: static bool classof(const MCFragment *F) { @@ -164,6 +152,32 @@ return true; } } + + /// Should this fragment be placed at the end of an aligned bundle? + bool alignToBundleEnd() const { return AlignToBundleEnd; } + void setAlignToBundleEnd(bool V) { AlignToBundleEnd = V; } + + /// 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. + uint8_t getBundlePadding() const { return BundlePadding; } + + /// Set the padding size for this fragment. By default it's a no-op, + /// and only some fragments have a meaningful implementation. + void setBundlePadding(uint8_t N) { BundlePadding = N; } + + /// Retrieve the MCSubTargetInfo in effect when the instruction was encoded. + /// Guaranteed to be non-null if hasInstructions() == true + const MCSubtargetInfo *getSubtargetInfo() const { return STI; } + + /// Record that the fragment contains instructions with the MCSubtargetInfo in + /// effect when the instruction was encoded. + void setHasInstructions(const MCSubtargetInfo &STI) { + HasInstructions = true; + this->STI = &STI; + } }; /// Interface implemented by fragments that contain encoded instructions and/or @@ -201,16 +215,8 @@ : MCEncodedFragmentWithContents(FType, HasInstructions, Sec) {} - /// STI - The MCSubtargetInfo in effect when the instruction was encoded. - /// must be non-null for instructions. - const MCSubtargetInfo *STI = nullptr; - public: - /// Retrieve the MCSubTargetInfo in effect when the instruction was encoded. - /// Guaranteed to be non-null if hasInstructions() == true - const MCSubtargetInfo *getSubtargetInfo() const { return STI; } - using const_fixup_iterator = SmallVectorImpl::const_iterator; using fixup_iterator = SmallVectorImpl::iterator; @@ -237,13 +243,6 @@ MCDataFragment(MCSection *Sec = nullptr) : MCEncodedFragmentWithFixups<32, 4>(FT_Data, false, Sec) {} - /// Record that the fragment contains instructions with the MCSubtargetInfo in - /// effect when the instruction was encoded. - void setHasInstructions(const MCSubtargetInfo &STI) { - HasInstructions = true; - this->STI = &STI; - } - static bool classof(const MCFragment *F) { return F->getKind() == MCFragment::FT_Data; } @@ -309,9 +308,8 @@ public: MCAlignFragment(unsigned Alignment, int64_t Value, unsigned ValueSize, unsigned MaxBytesToEmit, MCSection *Sec = nullptr) - : MCFragment(FT_Align, false, 0, Sec), Alignment(Alignment), - EmitNops(false), Value(Value), - ValueSize(ValueSize), MaxBytesToEmit(MaxBytesToEmit) {} + : MCFragment(FT_Align, false, Sec), Alignment(Alignment), EmitNops(false), + Value(Value), ValueSize(ValueSize), MaxBytesToEmit(MaxBytesToEmit) {} /// \name Accessors /// @{ @@ -379,7 +377,7 @@ }; MCPaddingFragment(MCSection *Sec = nullptr) - : MCFragment(FT_Padding, false, 0, Sec), PaddingPoliciesMask(PFK_None), + : MCFragment(FT_Padding, false, Sec), PaddingPoliciesMask(PFK_None), IsInsertionPoint(false), Size(UINT64_C(0)), InstInfo({false, MCInst(), false, {0}}) {} @@ -439,7 +437,7 @@ public: MCFillFragment(uint64_t Value, uint8_t VSize, const MCExpr &NumValues, SMLoc Loc, MCSection *Sec = nullptr) - : MCFragment(FT_Fill, false, 0, Sec), Value(Value), ValueSize(VSize), + : MCFragment(FT_Fill, false, Sec), Value(Value), ValueSize(VSize), NumValues(NumValues), Loc(Loc) {} uint64_t getValue() const { return Value; } @@ -466,7 +464,7 @@ public: MCOrgFragment(const MCExpr &Offset, int8_t Value, SMLoc Loc, MCSection *Sec = nullptr) - : MCFragment(FT_Org, false, 0, Sec), Offset(&Offset), Value(Value), Loc(Loc) {} + : MCFragment(FT_Org, false, Sec), Offset(&Offset), Value(Value), Loc(Loc) {} /// \name Accessors /// @{ @@ -495,7 +493,7 @@ public: MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSection *Sec = nullptr) - : MCFragment(FT_LEB, false, 0, Sec), Value(&Value_), IsSigned(IsSigned_) { + : MCFragment(FT_LEB, false, Sec), Value(&Value_), IsSigned(IsSigned_) { Contents.push_back(0); } @@ -530,7 +528,7 @@ public: MCDwarfLineAddrFragment(int64_t LineDelta, const MCExpr &AddrDelta, MCSection *Sec = nullptr) - : MCFragment(FT_Dwarf, false, 0, Sec), LineDelta(LineDelta), + : MCFragment(FT_Dwarf, false, Sec), LineDelta(LineDelta), AddrDelta(&AddrDelta) { Contents.push_back(0); } @@ -561,7 +559,7 @@ public: MCDwarfCallFrameFragment(const MCExpr &AddrDelta, MCSection *Sec = nullptr) - : MCFragment(FT_DwarfFrame, false, 0, Sec), AddrDelta(&AddrDelta) { + : MCFragment(FT_DwarfFrame, false, Sec), AddrDelta(&AddrDelta) { Contents.push_back(0); } @@ -586,7 +584,7 @@ public: MCSymbolIdFragment(const MCSymbol *Sym, MCSection *Sec = nullptr) - : MCFragment(FT_SymbolId, false, 0, Sec), Sym(Sym) {} + : MCFragment(FT_SymbolId, false, Sec), Sym(Sym) {} /// \name Accessors /// @{ @@ -620,7 +618,7 @@ unsigned StartLineNum, const MCSymbol *FnStartSym, const MCSymbol *FnEndSym, MCSection *Sec = nullptr) - : MCFragment(FT_CVInlineLines, false, 0, Sec), SiteFuncId(SiteFuncId), + : MCFragment(FT_CVInlineLines, false, Sec), SiteFuncId(SiteFuncId), StartFileId(StartFileId), StartLineNum(StartLineNum), FnStartSym(FnStartSym), FnEndSym(FnEndSym) {} Index: llvm/trunk/lib/MC/MCAssembler.cpp =================================================================== --- llvm/trunk/lib/MC/MCAssembler.cpp +++ llvm/trunk/lib/MC/MCAssembler.cpp @@ -426,17 +426,18 @@ if (Assembler.isBundlingEnabled() && F->hasInstructions()) { assert(isa(F) && "Only MCEncodedFragment implementations have instructions"); - uint64_t FSize = Assembler.computeFragmentSize(*this, *F); + MCEncodedFragment *EF = cast(F); + uint64_t FSize = Assembler.computeFragmentSize(*this, *EF); if (!Assembler.getRelaxAll() && FSize > Assembler.getBundleAlignSize()) report_fatal_error("Fragment can't be larger than a bundle size"); - uint64_t RequiredBundlePadding = computeBundlePadding(Assembler, F, - F->Offset, FSize); + uint64_t RequiredBundlePadding = + computeBundlePadding(Assembler, EF, EF->Offset, FSize); if (RequiredBundlePadding > UINT8_MAX) report_fatal_error("Padding cannot exceed 255 bytes"); - F->setBundlePadding(static_cast(RequiredBundlePadding)); - F->Offset += RequiredBundlePadding; + EF->setBundlePadding(static_cast(RequiredBundlePadding)); + EF->Offset += RequiredBundlePadding; } } @@ -450,19 +451,20 @@ } } -void MCAssembler::writeFragmentPadding(raw_ostream &OS, const MCFragment &F, +void MCAssembler::writeFragmentPadding(raw_ostream &OS, + const MCEncodedFragment &EF, uint64_t FSize) const { assert(getBackendPtr() && "Expected assembler backend"); // Should NOP padding be written out before this fragment? - unsigned BundlePadding = F.getBundlePadding(); + unsigned BundlePadding = EF.getBundlePadding(); if (BundlePadding > 0) { assert(isBundlingEnabled() && "Writing bundle padding with disabled bundling"); - assert(F.hasInstructions() && + assert(EF.hasInstructions() && "Writing bundle padding for a fragment without instructions"); unsigned TotalLength = BundlePadding + static_cast(FSize); - if (F.alignToBundleEnd() && TotalLength > getBundleAlignSize()) { + if (EF.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 @@ -473,8 +475,8 @@ // ^-------------------^ <- TotalLength unsigned DistanceToBoundary = TotalLength - getBundleAlignSize(); if (!getBackend().writeNopData(OS, DistanceToBoundary)) - report_fatal_error("unable to write NOP sequence of " + - Twine(DistanceToBoundary) + " bytes"); + report_fatal_error("unable to write NOP sequence of " + + Twine(DistanceToBoundary) + " bytes"); BundlePadding -= DistanceToBoundary; } if (!getBackend().writeNopData(OS, BundlePadding)) @@ -491,7 +493,8 @@ support::endianness Endian = Asm.getBackend().Endian; - Asm.writeFragmentPadding(OS, F, FragmentSize); + if (const MCEncodedFragment *EF = dyn_cast(&F)) + Asm.writeFragmentPadding(OS, *EF, FragmentSize); // This variable (and its dummy usage) is to participate in the assert at // the end of the function. Index: llvm/trunk/lib/MC/MCELFStreamer.cpp =================================================================== --- llvm/trunk/lib/MC/MCELFStreamer.cpp +++ llvm/trunk/lib/MC/MCELFStreamer.cpp @@ -557,6 +557,7 @@ MCCompactEncodedInstFragment *CEIF = new MCCompactEncodedInstFragment(); insert(CEIF); CEIF->getContents().append(Code.begin(), Code.end()); + CEIF->setHasInstructions(STI); return; } else { DF = new MCDataFragment(); Index: llvm/trunk/lib/MC/MCFragment.cpp =================================================================== --- llvm/trunk/lib/MC/MCFragment.cpp +++ llvm/trunk/lib/MC/MCFragment.cpp @@ -189,7 +189,7 @@ } uint64_t llvm::computeBundlePadding(const MCAssembler &Assembler, - const MCFragment *F, + const MCEncodedFragment *F, uint64_t FOffset, uint64_t FSize) { uint64_t BundleSize = Assembler.getBundleAlignSize(); assert(BundleSize > 0 && @@ -236,10 +236,9 @@ MCFragment::~MCFragment() = default; MCFragment::MCFragment(FragmentType Kind, bool HasInstructions, - uint8_t BundlePadding, MCSection *Parent) - : Kind(Kind), HasInstructions(HasInstructions), AlignToBundleEnd(false), - BundlePadding(BundlePadding), Parent(Parent), Atom(nullptr), - Offset(~UINT64_C(0)) { + MCSection *Parent) + : Kind(Kind), HasInstructions(HasInstructions), Parent(Parent), + Atom(nullptr), Offset(~UINT64_C(0)) { if (Parent && !isDummy()) Parent->getFragmentList().push_back(this); } @@ -333,10 +332,11 @@ case MCFragment::FT_Dummy: OS << "MCDummyFragment"; break; } - OS << "(getBundlePadding()) << ">"; + OS << "(this)) + OS << " BundlePadding:" << static_cast(EF->getBundlePadding()); + OS << ">"; switch (getKind()) { case MCFragment::FT_Align: {