Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(542)

Unified Diff: lib/MC/MCAssembler.cpp

Issue 5119002: Reuse data fragments while lowering (Closed) Base URL: http://llvm.org/svn/llvm-project/llvm/trunk/
Patch Set: Created 10 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « include/llvm/MC/MCAsmLayout.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/MC/MCAssembler.cpp
===================================================================
--- lib/MC/MCAssembler.cpp (revision 119741)
+++ lib/MC/MCAssembler.cpp (working copy)
@@ -113,14 +113,42 @@
}
}
-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 {
assert(F->getParent() && "Missing section()!");
return getSectionAddress(F->getParent()) + getFragmentOffset(F);
@@ -888,6 +916,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.
@@ -896,35 +940,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);
+ // Lower the Instruction Fragment
+ LowerInstFragment(IF, CurDF);
- // 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;
+ // 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++);
}
}
}
« no previous file with comments | « include/llvm/MC/MCAsmLayout.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698