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
diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp
index f05f6ac..0fbd77c 100644
--- a/lib/MC/MCAssembler.cpp
+++ b/lib/MC/MCAssembler.cpp
@@ -74,10 +74,9 @@
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 @@
}
}
-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::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(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 @@
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 @@
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 @@
// 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 @@
++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 @@
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 @@
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 @@
}
OS << "<MCFragment " << (void*) this << " LayoutOrder:" << LayoutOrder
- << " Offset:" << Offset << " EffectiveSize:" << EffectiveSize << ">";
+ << " Offset:" << Offset << ">";
switch (getKind()) {
case MCFragment::FT_Align: {