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

Daniel Dunbar daniel at zuster.org
Thu Mar 25 12:35:56 PDT 2010


Author: ddunbar
Date: Thu Mar 25 14:35:56 2010
New Revision: 99543

URL: http://llvm.org/viewvc/llvm-project?rev=99543&view=rev
Log:
MC: Stop restarting layout on every relaxation.
 - Still O(N^2), just a faster form, and now its the MCAsmLayout's fault.

On the .s I am tuning against (combine.s from 403.gcc):
--
ddunbar at lordcrumb:MC$ diff stats-before.txt stats-after.txt
5,10c5,10
<    1728 assembler - Number of assembler layout and relaxation steps
<    7707 assembler - Number of emitted assembler fragments
<  120588 assembler - Number of emitted object file bytes
< 2233448 assembler - Number of evaluated fixups
<    1727 assembler - Number of relaxed instructions
< 6723845 mcexpr    - Number of MCExpr evaluations
---
>      3 assembler - Number of assembler layout and relaxation steps
>   7707 assembler - Number of emitted assembler fragments
> 120588 assembler - Number of emitted object file bytes
>  14796 assembler - Number of evaluated fixups
>   1727 assembler - Number of relaxed instructions
>  67889 mcexpr    - Number of MCExpr evaluations
--
Feel free to LOL at the -before numbers, if you like.

I am a little surprised we make more than 2 relaxation passes. It's pretty
trivial for us to do relaxation out-of-order if that would give a speedup.

Modified:
    llvm/trunk/include/llvm/MC/MCAsmLayout.h
    llvm/trunk/include/llvm/MC/MCAssembler.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=99543&r1=99542&r2=99543&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCAsmLayout.h (original)
+++ llvm/trunk/include/llvm/MC/MCAsmLayout.h Thu Mar 25 14:35:56 2010
@@ -33,6 +33,11 @@
   /// Get the assembler object this is a layout for.
   MCAssembler &getAssembler() const { return Assembler; }
 
+  /// \brief Update the layout because a fragment has been resized. The
+  /// fragments size should have already been updated, the \arg SlideAmount is
+  /// the delta from the old size.
+  void UpdateForSlide(MCFragment *F, int SlideAmount);
+
   /// @name Fragment Layout Data
   /// @{
 

Modified: llvm/trunk/include/llvm/MC/MCAssembler.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCAssembler.h?rev=99543&r1=99542&r2=99543&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCAssembler.h (original)
+++ llvm/trunk/include/llvm/MC/MCAssembler.h Thu Mar 25 14:35:56 2010
@@ -580,6 +580,8 @@
 };
 
 class MCAssembler {
+  friend class MCAsmLayout;
+
 public:
   typedef iplist<MCSectionData> SectionDataListType;
   typedef iplist<MCSymbolData> SymbolDataListType;

Modified: llvm/trunk/lib/MC/MCAssembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAssembler.cpp?rev=99543&r1=99542&r2=99543&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCAssembler.cpp (original)
+++ llvm/trunk/lib/MC/MCAssembler.cpp Thu Mar 25 14:35:56 2010
@@ -45,6 +45,39 @@
 
 /* *** */
 
+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 are
+  // can guarantee convergence.
+  assert(SlideAmount >= 0 && "Negative slides not yet supported");
+
+  // 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.
+
+  // 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;
+
+    // Layout the section fragments and its size.
+    Address = Asm.LayoutSection(*it, *this, Address);
+  }
+}
+
 uint64_t MCAsmLayout::getFragmentAddress(const MCFragment *F) const {
   assert(F->getParent() && "Missing section()!");
   return getSectionAddress(F->getParent()) + getFragmentOffset(F);
@@ -716,6 +749,7 @@
   }
 
   // Scan for fragments that need relaxation.
+  bool WasRelaxed = false;
   for (iterator it = begin(), ie = end(); it != ie; ++it) {
     MCSectionData &SD = *it;
 
@@ -747,6 +781,7 @@
       VecOS.flush();
 
       // Update the instruction fragment.
+      int SlideAmount = Code.size() - IF->getInstSize();
       IF->setInst(Relaxed);
       IF->getCode() = Code;
       IF->getFixups().clear();
@@ -756,15 +791,13 @@
                                              F.getKind()));
       }
 
-      // Restart layout.
-      //
-      // FIXME-PERF: This is O(N^2), but will be eliminated once we have a
-      // smart MCAsmLayout object.
-      return true;
+      // Update the layout, and remember that we relaxed.
+      Layout.UpdateForSlide(IF, SlideAmount);
+      WasRelaxed = true;
     }
   }
 
-  return false;
+  return WasRelaxed;
 }
 
 void MCAssembler::FinishLayout(MCAsmLayout &Layout) {





More information about the llvm-commits mailing list