[llvm-commits] [llvm] r103753 - in /llvm/trunk: include/llvm/MC/MCAsmLayout.h lib/MC/MCAssembler.cpp
Daniel Dunbar
daniel at zuster.org
Thu May 13 17:37:21 PDT 2010
Author: ddunbar
Date: Thu May 13 19:37:21 2010
New Revision: 103753
URL: http://llvm.org/viewvc/llvm-project?rev=103753&view=rev
Log:
MC: Extend MCAsmLayout to explicitly track which fragments have been layed out, and enforce several invariants to LayoutFragment to ensure we only do layout in a sensible order.
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=103753&r1=103752&r2=103753&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCAsmLayout.h (original)
+++ llvm/trunk/include/llvm/MC/MCAsmLayout.h Thu May 13 19:37:21 2010
@@ -36,6 +36,14 @@
/// List of sections in layout order.
llvm::SmallVector<MCSectionData*, 16> SectionOrder;
+ /// The last fragment which was layed out, or 0 if nothing has been layed
+ /// out. Fragments are always layed out in order, so all fragments with a
+ /// lower ordinal will be up to date.
+ mutable MCFragment *LastValidFragment;
+
+ bool isSectionUpToDate(const MCSectionData *SD) const;
+ bool isFragmentUpToDate(const MCFragment *F) const;
+
public:
MCAsmLayout(MCAssembler &_Assembler);
Modified: llvm/trunk/lib/MC/MCAssembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAssembler.cpp?rev=103753&r1=103752&r2=103753&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCAssembler.cpp (original)
+++ llvm/trunk/lib/MC/MCAssembler.cpp Thu May 13 19:37:21 2010
@@ -47,7 +47,9 @@
/* *** */
-MCAsmLayout::MCAsmLayout(MCAssembler &Asm) : Assembler(Asm) {
+MCAsmLayout::MCAsmLayout(MCAssembler &Asm)
+ : Assembler(Asm), LastValidFragment(0)
+ {
// Compute the section layout order. Virtual sections must go last.
for (MCAssembler::iterator it = Asm.begin(), ie = Asm.end(); it != ie; ++it)
if (!Asm.getBackend().isVirtualSection(it->getSection()))
@@ -57,6 +59,23 @@
SectionOrder.push_back(&*it);
}
+bool MCAsmLayout::isSectionUpToDate(const MCSectionData *SD) const {
+ // The first section is always up-to-date.
+ unsigned Index = SD->getLayoutOrder();
+ if (!Index)
+ return true;
+
+ // Otherwise, sections are always implicitly computed when the preceeding
+ // fragment is layed out.
+ const MCSectionData *Prev = getSectionOrder()[Index - 1];
+ return isFragmentUpToDate(&(Prev->getFragmentList().back()));
+}
+
+bool MCAsmLayout::isFragmentUpToDate(const MCFragment *F) const {
+ return (LastValidFragment &&
+ F->getLayoutOrder() <= LastValidFragment->getLayoutOrder());
+}
+
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
@@ -73,6 +92,9 @@
}
void MCAsmLayout::FragmentReplaced(MCFragment *Src, MCFragment *Dst) {
+ if (LastValidFragment == Src)
+ LastValidFragment = Dst;
+
Dst->Offset = Src->Offset;
Dst->EffectiveSize = Src->EffectiveSize;
}
@@ -414,7 +436,8 @@
}
void MCAsmLayout::LayoutFile() {
- // Initialize the first section.
+ // Initialize the first section and set the valid fragment layout point.
+ LastValidFragment = 0;
if (!getSectionOrder().empty())
getSectionOrder().front()->Address = 0;
@@ -428,21 +451,32 @@
}
void MCAsmLayout::LayoutFragment(MCFragment *F) {
- uint64_t StartAddress = getSectionAddress(F->getParent());
+ MCFragment *Prev = F->getPrevNode();
- // Get the fragment start address.
- uint64_t Address = StartAddress;
- MCSectionData::iterator it = F;
- if (MCFragment *Prev = F->getPrevNode())
- Address = (StartAddress + getFragmentOffset(Prev) +
- getFragmentEffectiveSize(Prev));
+ // We should never try to recompute something which is up-to-date.
+ assert(!isFragmentUpToDate(F) && "Attempt to recompute up-to-date fragment!");
+ // We should never try to compute the fragment layout if the section isn't
+ // up-to-date.
+ assert(isSectionUpToDate(F->getParent()) &&
+ "Attempt to compute fragment before it's section!");
+ // We should never try to compute the fragment layout if it's predecessor
+ // isn't up-to-date.
+ assert((!Prev || isFragmentUpToDate(Prev)) &&
+ "Attempt to compute fragment before it's predecessor!");
++stats::FragmentLayouts;
+ // Compute the fragment start address.
+ uint64_t StartAddress = F->getParent()->Address;
+ uint64_t Address = StartAddress;
+ if (Prev)
+ Address += Prev->Offset + Prev->EffectiveSize;
+
// Compute fragment offset and size.
F->Offset = Address - StartAddress;
F->EffectiveSize = getAssembler().ComputeFragmentSize(*this, *F, StartAddress,
F->Offset);
+ LastValidFragment = F;
// If this is the last fragment in a section, update the next section address.
if (!F->getNextNode()) {
More information about the llvm-commits
mailing list