[llvm-commits] [llvm] r119999 - in /llvm/trunk: include/llvm/MC/MCAsmLayout.h lib/MC/MCAssembler.cpp
Rafael Espindola
rafael.espindola at gmail.com
Mon Nov 22 21:49:36 PST 2010
Author: rafael
Date: Mon Nov 22 23:49:35 2010
New Revision: 119999
URL: http://llvm.org/viewvc/llvm-project?rev=119999&view=rev
Log:
Reuse data fragments while lowering. Patch by David Meyer.
Modified:
llvm/trunk/include/llvm/MC/MCAsmLayout.h
llvm/trunk/lib/MC/MCAssembler.cpp
Modified: llvm/trunk/include/llvm/MC/MCAsmLayout.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCAsmLayout.h?rev=119999&r1=119998&r2=119999&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCAsmLayout.h (original)
+++ llvm/trunk/include/llvm/MC/MCAsmLayout.h Mon Nov 22 23:49:35 2010
@@ -59,8 +59,15 @@
/// the delta from the old size.
void UpdateForSlide(MCFragment *F, int SlideAmount);
- /// \brief Update the layout because a fragment has been replaced.
- void FragmentReplaced(MCFragment *Src, MCFragment *Dst);
+ /// \brief Update the layout, replacing Src with Dst. The contents
+ /// of Src and Dst are not modified, and must be copied by the caller.
+ /// Src will be removed from the layout, but not deleted.
+ void ReplaceFragment(MCFragment *Src, MCFragment *Dst);
+
+ /// \brief Update the layout to coalesce Src into Dst. The contents
+ /// of Src and Dst are not modified, and must be coalesced by the caller.
+ /// Src will be removed from the layout, but not deleted.
+ void CoalesceFragments(MCFragment *Src, MCFragment *Dst);
/// \brief Perform a full layout.
void LayoutFile();
Modified: llvm/trunk/lib/MC/MCAssembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAssembler.cpp?rev=119999&r1=119998&r2=119999&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCAssembler.cpp (original)
+++ llvm/trunk/lib/MC/MCAssembler.cpp Mon Nov 22 23:49:35 2010
@@ -113,12 +113,40 @@
}
}
-void MCAsmLayout::FragmentReplaced(MCFragment *Src, MCFragment *Dst) {
+void MCAsmLayout::ReplaceFragment(MCFragment *Src, MCFragment *Dst) {
+ MCSectionData *SD = Src->getParent();
+
+ // Insert Dst immediately before Src
+ SD->getFragmentList().insert(Src, Dst);
+
+ // Set the data fragment's layout data.
+ Dst->setParent(Src->getParent());
+ Dst->setAtom(Src->getAtom());
+ Dst->setLayoutOrder(Src->getLayoutOrder());
+
if (LastValidFragment == Src)
LastValidFragment = Dst;
Dst->Offset = Src->Offset;
Dst->EffectiveSize = Src->EffectiveSize;
+
+ // Remove Src, but don't delete it yet.
+ SD->getFragmentList().remove(Src);
+}
+
+void MCAsmLayout::CoalesceFragments(MCFragment *Src, MCFragment *Dst) {
+ assert(Src->getPrevNode() == Dst);
+
+ if (isFragmentUpToDate(Src)) {
+ if (LastValidFragment == Src)
+ LastValidFragment = Dst;
+ Dst->EffectiveSize += Src->EffectiveSize;
+ } else {
+ // We don't know the effective size of Src, so we have to invalidate Dst.
+ UpdateForSlide(Dst, 0);
+ }
+ // Remove Src, but don't delete it yet.
+ Src->getParent()->getFragmentList().remove(Src);
}
uint64_t MCAsmLayout::getFragmentAddress(const MCFragment *F) const {
@@ -890,6 +918,22 @@
return WasRelaxed;
}
+static void LowerInstFragment(MCInstFragment *IF,
+ MCDataFragment *DF) {
+
+ uint64_t DataOffset = DF->getContents().size();
+
+ // Copy in the data
+ DF->getContents().append(IF->getCode().begin(), IF->getCode().end());
+
+ // Adjust the fixup offsets and add them to the data fragment.
+ for (unsigned i = 0, e = IF->getFixups().size(); i != e; ++i) {
+ MCFixup &F = IF->getFixups()[i];
+ F.setOffset(DataOffset + F.getOffset());
+ DF->getFixups().push_back(F);
+ }
+}
+
void MCAssembler::FinishLayout(MCAsmLayout &Layout) {
// Lower out any instruction fragments, to simplify the fixup application and
// output.
@@ -898,35 +942,42 @@
// cheap (we will mostly end up eliminating fragments and appending on to data
// fragments), so the extra complexity downstream isn't worth it. Evaluate
// this assumption.
- for (iterator it = begin(), ie = end(); it != ie; ++it) {
- MCSectionData &SD = *it;
+ unsigned FragmentIndex = 0;
+ for (unsigned i = 0, e = Layout.getSectionOrder().size(); i != e; ++i) {
+ MCSectionData &SD = *Layout.getSectionOrder()[i];
+ MCDataFragment *CurDF = NULL;
for (MCSectionData::iterator it2 = SD.begin(),
ie2 = SD.end(); it2 != ie2; ++it2) {
- MCInstFragment *IF = dyn_cast<MCInstFragment>(it2);
- if (!IF)
- continue;
+ switch (it2->getKind()) {
+ default:
+ CurDF = NULL;
+ break;
+ case MCFragment::FT_Data:
+ CurDF = cast<MCDataFragment>(it2);
+ break;
+ case MCFragment::FT_Inst: {
+ MCInstFragment *IF = cast<MCInstFragment>(it2);
+ // Use the existing data fragment if possible.
+ if (CurDF && CurDF->getAtom() == IF->getAtom()) {
+ Layout.CoalesceFragments(IF, CurDF);
+ } else {
+ // Otherwise, create a new data fragment.
+ CurDF = new MCDataFragment();
+ Layout.ReplaceFragment(IF, CurDF);
+ }
- // Create a new data fragment for the instruction.
- //
- // FIXME-PERF: Reuse previous data fragment if possible.
- MCDataFragment *DF = new MCDataFragment();
- SD.getFragmentList().insert(it2, DF);
-
- // Update the data fragments layout data.
- DF->setParent(IF->getParent());
- DF->setAtom(IF->getAtom());
- DF->setLayoutOrder(IF->getLayoutOrder());
- Layout.FragmentReplaced(IF, DF);
-
- // Copy in the data and the fixups.
- DF->getContents().append(IF->getCode().begin(), IF->getCode().end());
- for (unsigned i = 0, e = IF->getFixups().size(); i != e; ++i)
- DF->getFixups().push_back(IF->getFixups()[i]);
-
- // Delete the instruction fragment and update the iterator.
- SD.getFragmentList().erase(IF);
- it2 = DF;
+ // Lower the Instruction Fragment
+ LowerInstFragment(IF, CurDF);
+
+ // Delete the instruction fragment and update the iterator.
+ delete IF;
+ it2 = CurDF;
+ break;
+ }
+ }
+ // Since we may have merged fragments, fix the layout order.
+ it2->setLayoutOrder(FragmentIndex++);
}
}
}
More information about the llvm-commits
mailing list