diff options
-rw-r--r-- | include/llvm/MC/MCAssembler.h | 22 | ||||
-rw-r--r-- | lib/MC/MCAssembler.cpp | 70 | ||||
-rw-r--r-- | lib/MC/MCELFStreamer.cpp | 13 |
3 files changed, 17 insertions, 88 deletions
diff --git a/include/llvm/MC/MCAssembler.h b/include/llvm/MC/MCAssembler.h index 7c1ba4ef6c..b577f92ae8 100644 --- a/include/llvm/MC/MCAssembler.h +++ b/include/llvm/MC/MCAssembler.h @@ -532,26 +532,18 @@ private: unsigned HasInstructions : 1; // @LOCALMOD-BEGIN - bool BundlingEnabled : 1; - bool BundleLocked : 1; + bool BundlingEnabled; + bool BundleLocked; // Because ".bundle_lock" occurs before the fragment it applies to exists, // we need to keep this flag around so we know to mark the next fragment // as the start of a bundle group. A similar flag is not necessary for the // last fragment, because when a .bundle_unlock occurs, the last fragment // in the group already exists and can be marked directly. - bool BundleGroupFirstFrag : 1; + bool BundleGroupFirstFrag; typedef MCFragment::BundleAlignType BundleAlignType; - BundleAlignType BundleAlignNext : 2; - - // Optimization to reduce the number of fragments generated (for memory - // savings). Keep track of when we know the offset of the next point to - // emit an instruction. If we know the offset from a known alignment point, - // we can just append to the previous fragment. - bool BundleOffsetKnown : 1; - unsigned BundleSize; - unsigned BundleOffset; + BundleAlignType BundleAlignNext; // @LOCALMOD-END /// @} @@ -564,7 +556,7 @@ public: const MCSection &getSection() const { return *Section; } unsigned getAlignment() const { return Alignment; } - void setAlignment(unsigned Value); // @LOCALMOD + void setAlignment(unsigned Value) { Alignment = Value; } bool hasInstructions() const { return HasInstructions; } void setHasInstructions(bool Value) { HasInstructions = Value; } @@ -587,10 +579,6 @@ public: BundleAlignType getBundleAlignNext() const { return BundleAlignNext; } void setBundleAlignNext(BundleAlignType Value) { BundleAlignNext = Value; } - - void MarkBundleOffsetUnknown(); - bool ShouldCreateNewFragment(size_t Size); - void UpdateBundleOffset(size_t Size); // @LOCALMOD-END /// @name Fragment Access diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp index 76dac99850..321b2832b9 100644 --- a/lib/MC/MCAssembler.cpp +++ b/lib/MC/MCAssembler.cpp @@ -186,14 +186,13 @@ MCFragment::~MCFragment() { } MCFragment::MCFragment(FragmentType _Kind, MCSectionData *_Parent) - : Kind(_Kind), + : Kind(_Kind), Parent(_Parent), Atom(0), Offset(~UINT64_C(0)), // @LOCALMOD-BEGIN BundleAlign(BundleAlignNone), BundleGroupStart(false), BundleGroupEnd(false), - BundlePadding(~UINT8_C(0)), + BundlePadding(~UINT8_C(0)) // @LOCALMOD-END - Parent(_Parent), Atom(0), Offset(~UINT64_C(0)) { if (Parent) Parent->getFragmentList().push_back(this); @@ -227,16 +226,14 @@ MCSectionData::MCSectionData(const MCSection &_Section, MCAssembler *A) BundlingEnabled(false), BundleLocked(false), BundleGroupFirstFrag(false), - BundleAlignNext(MCFragment::BundleAlignNone), - BundleOffsetKnown(false), - BundleOffset(0) + BundleAlignNext(MCFragment::BundleAlignNone) // @LOCALMOD-END { if (A) A->getSectionList().push_back(this); // @LOCALMOD-BEGIN - BundleSize = A->getBackend().getBundleSize(); + unsigned BundleSize = A->getBackend().getBundleSize(); if (BundleSize && _Section.UseCodeAlign()) { BundlingEnabled = true; setAlignment(BundleSize); @@ -244,65 +241,6 @@ MCSectionData::MCSectionData(const MCSection &_Section, MCAssembler *A) // @LOCALMOD-END } -// @LOCALMOD-BEGIN -void MCSectionData::setAlignment(unsigned Value) { - Alignment = Value; - // If the alignment is at least as big as a bundle, then we know the offset - // relative to the start of a bundle. - if (Alignment >= BundleSize) { - BundleOffsetKnown = true; - BundleOffset = 0; - } else { - BundleOffsetKnown = false; - BundleOffset = 0; - } -} - -void MCSectionData::MarkBundleOffsetUnknown() { - BundleOffsetKnown = false; - BundleOffset = 0; -} - -// Only create a new fragment if: -// 1) we are emitting the first instruction of a bundle locked sequence. -// 2) we are not currently emitting a bundle locked sequence and we cannot -// guarantee the instruction would not span a bundle boundary. -// Otherwise, append to the current fragment to reduce the number of fragments. -bool MCSectionData::ShouldCreateNewFragment(size_t Size) { - // The first instruction of a bundle locked region starts a new fragment. - if (isBundleLocked() && isBundleGroupFirstFrag()) - return true; - // Unless we know the relative offset of the end of the current fragment, - // we need to create a new fragment. - if (!isBundleLocked() && !BundleOffsetKnown) - return true; - assert(BundleSize != 0 && "BundleSize needs to be non-zero"); - assert(Size < BundleSize && "Instruction size must be less than BundleSize"); - // If inserting the instruction would overlap a bundle boundary, start a - // new fragment. - // TODO(sehr): we could still explicitly insert a NOP and continue here. - if (BundleOffset + (unsigned) Size > BundleSize) - return true; - return false; -} - -void MCSectionData::UpdateBundleOffset(size_t Size) { - // A bundle locked fragment could move if it spans a bundle boundary. - if (isBundleLocked()) { - BundleOffsetKnown = false; - return; - } - // If inserting the instruction would overlap a bundle boundary, starting a - // new fragment moves the known offset to the end of the instruction in the - // next bundle. - // TODO(sehr): we could insert a NOP and continue the fragment. - if (BundleOffset + (unsigned) Size > BundleSize) - BundleOffset = Size; - else - BundleOffset = BundleOffset + Size; -} -// @LOCALMOD-END - /* *** */ MCSymbolData::MCSymbolData() : Symbol(0) {} diff --git a/lib/MC/MCELFStreamer.cpp b/lib/MC/MCELFStreamer.cpp index 6d7c78bb22..26b171ed21 100644 --- a/lib/MC/MCELFStreamer.cpp +++ b/lib/MC/MCELFStreamer.cpp @@ -359,7 +359,6 @@ void MCELFStreamer::EmitBytes(StringRef Data, unsigned AddrSpace) { // TODO: This is exactly the same as WinCOFFStreamer. Consider merging into // MCObjectStreamer. getOrCreateDataFragment()->getContents().append(Data.begin(), Data.end()); - getCurrentSectionData()->MarkBundleOffsetUnknown(); // @LOCALMOD } void MCELFStreamer::EmitValueToAlignment(unsigned ByteAlignment, @@ -396,7 +395,6 @@ void MCELFStreamer::EmitValueImpl(const MCExpr *Value, unsigned Size, unsigned AddrSpace) { fixSymbolsInTLSFixups(Value); MCObjectStreamer::EmitValueImpl(Value, Size, AddrSpace); - getCurrentSectionData()->MarkBundleOffsetUnknown(); // @LOCALMOD } @@ -465,7 +463,6 @@ void MCELFStreamer::EmitInstToFragment(const MCInst &Inst) { for (unsigned i = 0, e = F.getFixups().size(); i != e; ++i) fixSymbolsInTLSFixups(F.getFixups()[i].getValue()); - getCurrentSectionData()->MarkBundleOffsetUnknown(); // @LOCALMOD } void MCELFStreamer::EmitInstToData(const MCInst &Inst) { @@ -490,12 +487,18 @@ void MCELFStreamer::EmitInstToData(const MCInst &Inst) { } DF->getContents().append(Code.begin(), Code.end()); } else { + // Only create a new fragment if: + // 1) there is no current fragment, + // 2) we are not currently emitting a bundle locked sequence, or + // 3) we are emitting the first instruction of a bundle locked sequence. + // Otherwise, append to the current fragment to reduce the number of + // fragments. MCTinyFragment *TF = dyn_cast_or_null<MCTinyFragment>(getCurrentFragment()); MCSectionData *SD = getCurrentSectionData(); - if (!TF || SD->ShouldCreateNewFragment(Code.size())) + if (!TF || !SD->isBundleLocked() || SD->isBundleGroupFirstFrag()) { TF = new MCTinyFragment(SD); + } TF->getContents().append(Code.begin(), Code.end()); - SD->UpdateBundleOffset(Code.size()); } // @LOCALMOD-END } |