[llvm-commits] [llvm] r119999 - in /llvm/trunk: include/llvm/MC/MCAsmLayout.h lib/MC/MCAssembler.cpp

Rafael Espindola rafael.espindola at gmail.com
Mon Nov 22 21:49:36 PST 2010


Author: rafael
Date: Mon Nov 22 23:49:35 2010
New Revision: 119999

URL: http://llvm.org/viewvc/llvm-project?rev=119999&view=rev
Log:
Reuse data fragments while lowering. Patch by David Meyer.

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=119999&r1=119998&r2=119999&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCAsmLayout.h (original)
+++ llvm/trunk/include/llvm/MC/MCAsmLayout.h Mon Nov 22 23:49:35 2010
@@ -59,8 +59,15 @@
   /// the delta from the old size.
   void UpdateForSlide(MCFragment *F, int SlideAmount);
 
-  /// \brief Update the layout because a fragment has been replaced.
-  void FragmentReplaced(MCFragment *Src, MCFragment *Dst);
+  /// \brief Update the layout, replacing Src with Dst. The contents
+  /// of Src and Dst are not modified, and must be copied by the caller.
+  /// Src will be removed from the layout, but not deleted.
+  void ReplaceFragment(MCFragment *Src, MCFragment *Dst);
+
+  /// \brief Update the layout to coalesce Src into Dst. The contents
+  /// of Src and Dst are not modified, and must be coalesced by the caller.
+  /// Src will be removed from the layout, but not deleted.
+  void CoalesceFragments(MCFragment *Src, MCFragment *Dst);
 
   /// \brief Perform a full layout.
   void LayoutFile();

Modified: llvm/trunk/lib/MC/MCAssembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAssembler.cpp?rev=119999&r1=119998&r2=119999&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCAssembler.cpp (original)
+++ llvm/trunk/lib/MC/MCAssembler.cpp Mon Nov 22 23:49:35 2010
@@ -113,12 +113,40 @@
   }
 }
 
-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 {
@@ -890,6 +918,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.
@@ -898,35 +942,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);
-
-      // 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;
+        // Lower the Instruction Fragment
+        LowerInstFragment(IF, CurDF);
+
+        // 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++);
     }
   }
 }





More information about the llvm-commits mailing list