diff options
author | Daniel Dunbar <daniel@zuster.org> | 2010-05-14 00:51:14 +0000 |
---|---|---|
committer | Daniel Dunbar <daniel@zuster.org> | 2010-05-14 00:51:14 +0000 |
commit | 47b3ec4daa12019b98468e8f646501ec285bbb59 (patch) | |
tree | 2e0a430f6e382ac08b188f23300d8a33c937757f /lib/MC/MCAssembler.cpp | |
parent | 9005d45a990ef46f06800bd6bd6a7d1298a33645 (diff) | |
download | external_llvm-47b3ec4daa12019b98468e8f646501ec285bbb59.zip external_llvm-47b3ec4daa12019b98468e8f646501ec285bbb59.tar.gz external_llvm-47b3ec4daa12019b98468e8f646501ec285bbb59.tar.bz2 |
MC: Switch to completely lazy layout.
- The eliminates the last major algorithmic problem with MC.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@103754 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/MC/MCAssembler.cpp')
-rw-r--r-- | lib/MC/MCAssembler.cpp | 54 |
1 files changed, 35 insertions, 19 deletions
diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp index 411c6d9..199944d 100644 --- a/lib/MC/MCAssembler.cpp +++ b/lib/MC/MCAssembler.cpp @@ -77,18 +77,38 @@ bool MCAsmLayout::isFragmentUpToDate(const MCFragment *F) const { } 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::getFragmentAddress(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!"); return F->Offset; } @@ -120,6 +142,7 @@ uint64_t MCAsmLayout::getSymbolAddress(const MCSymbolData *SD) const { } 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 @@ uint64_t MCAssembler::ComputeFragmentSize(MCAsmLayout &Layout, } 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) { |