MC: Track section layout order explicitly, and use to simplify.
authorDaniel Dunbar <daniel@zuster.org>
Wed, 12 May 2010 15:42:59 +0000 (15:42 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Wed, 12 May 2010 15:42:59 +0000 (15:42 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@103616 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/MC/MCAsmLayout.h
lib/MC/MCAssembler.cpp

index ebf0520d091f0cdf0e1f493b079b057943644091..bfd177d995b1c5d4547ed647bc512fa68eb45395 100644 (file)
@@ -10,6 +10,8 @@
 #ifndef LLVM_MC_MCASMLAYOUT_H
 #define LLVM_MC_MCASMLAYOUT_H
 
+#include "llvm/ADT/SmallVector.h"
+
 namespace llvm {
 class MCAssembler;
 class MCFragment;
@@ -24,11 +26,18 @@ class MCSymbolData;
 /// efficiently compute the exact addresses of any symbol in the assembly file,
 /// even during the relaxation process.
 class MCAsmLayout {
+public:
+  typedef llvm::SmallVectorImpl<MCSectionData*>::const_iterator const_iterator;
+  typedef llvm::SmallVectorImpl<MCSectionData*>::iterator iterator;
+
 private:
   MCAssembler &Assembler;
 
+  /// List of sections in layout order.
+  llvm::SmallVector<MCSectionData*, 16> SectionOrder;
+
 public:
-  MCAsmLayout(MCAssembler &_Assembler) : Assembler(_Assembler) {}
+  MCAsmLayout(MCAssembler &_Assembler);
 
   /// Get the assembler object this is a layout for.
   MCAssembler &getAssembler() const { return Assembler; }
@@ -38,6 +47,16 @@ public:
   /// the delta from the old size.
   void UpdateForSlide(MCFragment *F, int SlideAmount);
 
+  /// @name Section Access (in layout order)
+  /// @{
+
+  iterator begin() { return SectionOrder.begin(); }
+  const_iterator begin() const { return SectionOrder.begin(); }
+
+  iterator end() {return SectionOrder.end();}
+  const_iterator end() const {return SectionOrder.end();}
+
+  /// @}
   /// @name Fragment Layout Data
   /// @{
 
index 8ec927e4150c5fe2d44617cf297cb6b7e993923b..60349e69aa21624086286aa20d55c4ff624572e0 100644 (file)
@@ -47,6 +47,16 @@ STATISTIC(SectionLayouts, "Number of section layouts");
 
 /* *** */
 
+MCAsmLayout::MCAsmLayout(MCAssembler &Asm) : Assembler(Asm) {
+  // 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()))
+      SectionOrder.push_back(&*it);
+  for (MCAssembler::iterator it = Asm.begin(), ie = Asm.end(); it != ie; ++it)
+    if (Asm.getBackend().isVirtualSection(it->getSection()))
+      SectionOrder.push_back(&*it);
+}
+
 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
@@ -59,24 +69,10 @@ void MCAsmLayout::UpdateForSlide(MCFragment *F, int SlideAmount) {
   // FIXME-PERF: This is O(N^2), but will be eliminated once we get smarter.
 
   // Layout the concrete sections and fragments.
-  MCAssembler &Asm = getAssembler();
   uint64_t Address = 0;
-  for (MCAssembler::iterator it = Asm.begin(), ie = Asm.end(); it != ie; ++it) {
-    // Skip virtual sections.
-    if (Asm.getBackend().isVirtualSection(it->getSection()))
-      continue;
-
-    // Layout the section fragments and its size.
-    Address = Asm.LayoutSection(*it, *this, Address);
-  }
-
-  // Layout the virtual sections.
-  for (MCAssembler::iterator it = Asm.begin(), ie = Asm.end(); it != ie; ++it) {
-    if (!Asm.getBackend().isVirtualSection(it->getSection()))
-      continue;
-
+  for (iterator it = begin(), ie = end(); it != ie; ++it) {
     // Layout the section fragments and its size.
-    Address = Asm.LayoutSection(*it, *this, Address);
+    Address = getAssembler().LayoutSection(**it, *this, Address);
   }
 }
 
@@ -711,22 +707,10 @@ bool MCAssembler::LayoutOnce(MCAsmLayout &Layout) {
 
   // Layout the concrete sections and fragments.
   uint64_t Address = 0;
-  for (iterator it = begin(), ie = end(); it != ie; ++it) {
-    // Skip virtual sections.
-    if (getBackend().isVirtualSection(it->getSection()))
-      continue;
-
-    // Layout the section fragments and its size.
-    Address = LayoutSection(*it, Layout, Address);
-  }
-
-  // Layout the virtual sections.
-  for (iterator it = begin(), ie = end(); it != ie; ++it) {
-    if (!getBackend().isVirtualSection(it->getSection()))
-      continue;
-
+  for (MCAsmLayout::iterator it = Layout.begin(),
+         ie = Layout.end(); it != ie; ++it) {
     // Layout the section fragments and its size.
-    Address = LayoutSection(*it, Layout, Address);
+    Address = LayoutSection(**it, Layout, Address);
   }
 
   // Scan for fragments that need relaxation.