[llvm-commits] [llvm] r103754 - in /llvm/trunk: include/llvm/MC/MCAsmLayout.h lib/MC/MCAssembler.cpp
Daniel Dunbar
daniel at zuster.org
Thu May 13 17:51:14 PDT 2010
Author: ddunbar
Date: Thu May 13 19:51:14 2010
New Revision: 103754
URL: http://llvm.org/viewvc/llvm-project?rev=103754&view=rev
Log:
MC: Switch to completely lazy layout.
- The eliminates the last major algorithmic problem with MC.
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=103754&r1=103753&r2=103754&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCAsmLayout.h (original)
+++ llvm/trunk/include/llvm/MC/MCAsmLayout.h Thu May 13 19:51:14 2010
@@ -41,6 +41,10 @@
/// lower ordinal will be up to date.
mutable MCFragment *LastValidFragment;
+ /// \brief Make sure that the layout for the given fragment is valid, lazily
+ /// computing it if necessary.
+ void EnsureValid(const MCFragment *F) const;
+
bool isSectionUpToDate(const MCSectionData *SD) const;
bool isFragmentUpToDate(const MCFragment *F) const;
Modified: llvm/trunk/lib/MC/MCAssembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAssembler.cpp?rev=103754&r1=103753&r2=103754&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCAssembler.cpp (original)
+++ llvm/trunk/lib/MC/MCAssembler.cpp Thu May 13 19:51:14 2010
@@ -77,18 +77,38 @@
}
void MCAsmLayout::UpdateForSlide(MCFragment *F, int SlideAmount) {
- // We shouldn't have to do anything special to support negative slides, and it
- // is a perfectly valid thing to do as long as other parts of the system can
- // guarantee convergence.
- assert(SlideAmount >= 0 && "Negative slides not yet supported");
+ // If this fragment wasn't already up-to-date, we don't need to do anything.
+ if (!isFragmentUpToDate(F))
+ return;
- // Update the layout by simply recomputing the layout for the entire
- // file. This is trivially correct, but very slow.
- //
- // FIXME-PERF: This is O(N^2), but will be eliminated once we get smarter.
+ // Otherwise, reset the last valid fragment to the predecessor of the
+ // invalidated fragment.
+ LastValidFragment = F->getPrevNode();
+ if (!LastValidFragment) {
+ unsigned Index = F->getParent()->getLayoutOrder();
+ if (Index != 0) {
+ MCSectionData *Prev = getSectionOrder()[Index - 1];
+ LastValidFragment = &(Prev->getFragmentList().back());
+ }
+ }
+}
- // Layout the sections in order.
- LayoutFile();
+void MCAsmLayout::EnsureValid(const MCFragment *F) const {
+ // Advance the layout position until the fragment is up-to-date.
+ while (!isFragmentUpToDate(F)) {
+ // Advance to the next fragment.
+ MCFragment *Cur = LastValidFragment;
+ if (Cur)
+ Cur = Cur->getNextNode();
+ if (!Cur) {
+ unsigned NextIndex = 0;
+ if (LastValidFragment)
+ NextIndex = LastValidFragment->getParent()->getLayoutOrder() + 1;
+ Cur = SectionOrder[NextIndex]->begin();
+ }
+
+ const_cast<MCAsmLayout*>(this)->LayoutFragment(Cur);
+ }
}
void MCAsmLayout::FragmentReplaced(MCFragment *Src, MCFragment *Dst) {
@@ -105,11 +125,13 @@
}
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!");
return F->Offset;
}
@@ -120,6 +142,7 @@
}
uint64_t MCAsmLayout::getSectionAddress(const MCSectionData *SD) const {
+ EnsureValid(SD->begin());
assert(SD->Address != ~UINT64_C(0) && "Address not set!");
return SD->Address;
}
@@ -436,18 +459,11 @@
}
void MCAsmLayout::LayoutFile() {
- // Initialize the first section and set the valid fragment layout point.
+ // Initialize the first section and set the valid fragment layout point. All
+ // actual layout computations are done lazily.
LastValidFragment = 0;
if (!getSectionOrder().empty())
getSectionOrder().front()->Address = 0;
-
- for (unsigned i = 0, e = getSectionOrder().size(); i != e; ++i) {
- MCSectionData *SD = getSectionOrder()[i];
-
- for (MCSectionData::iterator it = SD->begin(),
- ie = SD->end(); it != ie; ++it)
- LayoutFragment(it);
- }
}
void MCAsmLayout::LayoutFragment(MCFragment *F) {
More information about the llvm-commits
mailing list