diff options
author | Rafael Espindola <rafael.espindola@gmail.com> | 2010-12-15 08:45:53 +0000 |
---|---|---|
committer | Rafael Espindola <rafael.espindola@gmail.com> | 2010-12-15 08:45:53 +0000 |
commit | 2bf6afc277edb32b1d940def5b3eb0e0d32a22b9 (patch) | |
tree | cccbb7a607e07c1166a377006aa31956f5d5797d /lib/MC/MCAssembler.cpp | |
parent | f9a447617329186976fe5ab8b48fe3c9c0698bc7 (diff) |
Relax alignment fragments.
With this we don't need the EffectiveSize field anymore. Without that field
LayoutFragment only updates offsets and we don't need to invalidate the
current fragment when it is relaxed (only the ones following it).
This is also a very small improvement in the accuracy of the layout info as
we now use the after relaxation size immediately.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@121857 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC/MCAssembler.cpp')
-rw-r--r-- | lib/MC/MCAssembler.cpp | 55 |
1 files changed, 26 insertions, 29 deletions
diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp index f05f6acd63..0fbd77c7f1 100644 --- a/lib/MC/MCAssembler.cpp +++ b/lib/MC/MCAssembler.cpp @@ -74,10 +74,9 @@ void MCAsmLayout::Invalidate(MCFragment *F) { if (!isFragmentUpToDate(F)) return; - // Otherwise, reset the last valid fragment to the predecessor of the - // invalidated fragment. + // Otherwise, reset the last valid fragment to this fragment. const MCSectionData &SD = *F->getParent(); - LastValidFragment[&SD] = F->getPrevNode(); + LastValidFragment[&SD] = F; } void MCAsmLayout::EnsureValid(const MCFragment *F) const { @@ -96,12 +95,6 @@ void MCAsmLayout::EnsureValid(const MCFragment *F) const { } } -uint64_t MCAsmLayout::getFragmentEffectiveSize(const MCFragment *F) const { - EnsureValid(F); - assert(F->EffectiveSize != ~UINT64_C(0) && "Address not set!"); - return F->EffectiveSize; -} - uint64_t MCAsmLayout::getFragmentOffset(const MCFragment *F) const { EnsureValid(F); assert(F->Offset != ~UINT64_C(0) && "Address not set!"); @@ -116,7 +109,7 @@ uint64_t MCAsmLayout::getSymbolOffset(const MCSymbolData *SD) const { uint64_t MCAsmLayout::getSectionAddressSize(const MCSectionData *SD) const { // The size is the last fragment's end offset. const MCFragment &F = SD->getFragmentList().back(); - return getFragmentOffset(&F) + getFragmentEffectiveSize(&F); + return getFragmentOffset(&F) + getAssembler().ComputeFragmentSize(F); } uint64_t MCAsmLayout::getSectionFileSize(const MCSectionData *SD) const { @@ -137,8 +130,7 @@ MCFragment::~MCFragment() { } MCFragment::MCFragment(FragmentType _Kind, MCSectionData *_Parent) - : Kind(_Kind), Parent(_Parent), Atom(0), Offset(~UINT64_C(0)), - EffectiveSize(~UINT64_C(0)) + : Kind(_Kind), Parent(_Parent), Atom(0), Offset(~UINT64_C(0)) { if (Parent) Parent->getFragmentList().push_back(this); @@ -276,8 +268,7 @@ bool MCAssembler::EvaluateFixup(const MCObjectWriter &Writer, return IsResolved; } -uint64_t MCAssembler::ComputeFragmentSize(const MCFragment &F, - uint64_t FragmentOffset) const { +uint64_t MCAssembler::ComputeFragmentSize(const MCFragment &F) const { switch (F.getKind()) { case MCFragment::FT_Data: return cast<MCDataFragment>(F).getContents().size(); @@ -289,17 +280,8 @@ uint64_t MCAssembler::ComputeFragmentSize(const MCFragment &F, case MCFragment::FT_LEB: return cast<MCLEBFragment>(F).getContents().size(); - case MCFragment::FT_Align: { - const MCAlignFragment &AF = cast<MCAlignFragment>(F); - - uint64_t Size = OffsetToAlignment(FragmentOffset, AF.getAlignment()); - - // Honor MaxBytesToEmit. - if (Size > AF.getMaxBytesToEmit()) - return 0; - - return Size; - } + case MCFragment::FT_Align: + return cast<MCAlignFragment>(F).getSize(); case MCFragment::FT_Org: return cast<MCOrgFragment>(F).getSize(); @@ -327,10 +309,9 @@ void MCAsmLayout::LayoutFragment(MCFragment *F) { // Compute fragment offset and size. uint64_t Offset = 0; if (Prev) - Offset += Prev->Offset + Prev->EffectiveSize; + Offset += Prev->Offset + getAssembler().ComputeFragmentSize(*Prev); F->Offset = Offset; - F->EffectiveSize = getAssembler().ComputeFragmentSize(*F, F->Offset); LastValidFragment[F->getParent()] = F; } @@ -343,7 +324,7 @@ static void WriteFragmentData(const MCAssembler &Asm, const MCAsmLayout &Layout, ++stats::EmittedFragments; // FIXME: Embed in fragments instead? - uint64_t FragmentSize = Layout.getFragmentEffectiveSize(&F); + uint64_t FragmentSize = Asm.ComputeFragmentSize(F); switch (F.getKind()) { case MCFragment::FT_Align: { MCAlignFragment &AF = cast<MCAlignFragment>(F); @@ -730,6 +711,18 @@ bool MCAssembler::RelaxDwarfLineAddr(const MCObjectWriter &Writer, return OldSize != Data.size(); } +bool MCAssembler::RelaxAlignment(const MCObjectWriter &Writer, + MCAsmLayout &Layout, + MCAlignFragment &AF) { + unsigned Offset = Layout.getFragmentOffset(&AF); + unsigned Size = OffsetToAlignment(Offset, AF.getAlignment()); + if (Size > AF.getMaxBytesToEmit()) + Size = 0; + unsigned OldSize = AF.getSize(); + AF.setSize(Size); + return OldSize != Size; +} + bool MCAssembler::LayoutOnce(const MCObjectWriter &Writer, MCAsmLayout &Layout) { ++stats::RelaxationSteps; @@ -747,6 +740,10 @@ bool MCAssembler::LayoutOnce(const MCObjectWriter &Writer, switch(it2->getKind()) { default: break; + case MCFragment::FT_Align: + relaxedFrag = RelaxAlignment(Writer, Layout, + *cast<MCAlignFragment>(it2)); + break; case MCFragment::FT_Inst: relaxedFrag = RelaxInstruction(Writer, Layout, *cast<MCInstFragment>(it2)); @@ -809,7 +806,7 @@ void MCFragment::dump() { } OS << "<MCFragment " << (void*) this << " LayoutOrder:" << LayoutOrder - << " Offset:" << Offset << " EffectiveSize:" << EffectiveSize << ">"; + << " Offset:" << Offset << ">"; switch (getKind()) { case MCFragment::FT_Align: { |