[llvm-commits] [llvm] r121857 - in /llvm/trunk: include/llvm/MC/MCAsmLayout.h include/llvm/MC/MCAssembler.h lib/MC/MCAssembler.cpp test/MC/MachO/relax-recompute-align.s

Rafael Espindola rafael.espindola at gmail.com
Wed Dec 15 00:45:53 PST 2010


Author: rafael
Date: Wed Dec 15 02:45:53 2010
New Revision: 121857

URL: http://llvm.org/viewvc/llvm-project?rev=121857&view=rev
Log:
Relax alignment fragments.

With this we don't need the EffectiveSize field anymore. Without that field
LayoutFragment only updates offsets and we don't need to invalidate the
current fragment when it is relaxed (only the ones following it).

This is also a very small improvement in the accuracy of the layout info as
we now use the after relaxation size immediately.

Modified:
    llvm/trunk/include/llvm/MC/MCAsmLayout.h
    llvm/trunk/include/llvm/MC/MCAssembler.h
    llvm/trunk/lib/MC/MCAssembler.cpp
    llvm/trunk/test/MC/MachO/relax-recompute-align.s

Modified: llvm/trunk/include/llvm/MC/MCAsmLayout.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCAsmLayout.h?rev=121857&r1=121856&r2=121857&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCAsmLayout.h (original)
+++ llvm/trunk/include/llvm/MC/MCAsmLayout.h Wed Dec 15 02:45:53 2010
@@ -76,10 +76,6 @@
   /// @name Fragment Layout Data
   /// @{
 
-  /// \brief Get the effective size of the given fragment, as computed in the
-  /// current layout.
-  uint64_t getFragmentEffectiveSize(const MCFragment *F) const;
-
   /// \brief Get the offset of the given fragment inside its containing section.
   uint64_t getFragmentOffset(const MCFragment *F) const;
 

Modified: llvm/trunk/include/llvm/MC/MCAssembler.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCAssembler.h?rev=121857&r1=121856&r2=121857&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCAssembler.h (original)
+++ llvm/trunk/include/llvm/MC/MCAssembler.h Wed Dec 15 02:45:53 2010
@@ -75,10 +75,6 @@
   /// initialized.
   uint64_t Offset;
 
-  /// EffectiveSize - The compute size of this section. This is ~0 until
-  /// initialized.
-  uint64_t EffectiveSize;
-
   /// LayoutOrder - The layout order of this fragment.
   unsigned LayoutOrder;
 
@@ -231,6 +227,9 @@
   /// cannot be satisfied in this width then this fragment is ignored.
   unsigned MaxBytesToEmit;
 
+  /// Size - The current estimate of the size.
+  unsigned Size;
+
   /// EmitNops - Flag to indicate that (optimal) NOPs should be emitted instead
   /// of using the provided value. The exact interpretation of this flag is
   /// target dependent.
@@ -241,7 +240,7 @@
                   unsigned _MaxBytesToEmit, MCSectionData *SD = 0)
     : MCFragment(FT_Align, SD), Alignment(_Alignment),
       Value(_Value),ValueSize(_ValueSize),
-      MaxBytesToEmit(_MaxBytesToEmit), EmitNops(false) {}
+      MaxBytesToEmit(_MaxBytesToEmit), Size(0), EmitNops(false) {}
 
   /// @name Accessors
   /// @{
@@ -252,6 +251,10 @@
 
   unsigned getValueSize() const { return ValueSize; }
 
+  unsigned getSize() const { return Size; }
+
+  void setSize(unsigned Size_) { Size = Size_; }
+
   unsigned getMaxBytesToEmit() const { return MaxBytesToEmit; }
 
   bool hasEmitNops() const { return EmitNops; }
@@ -704,11 +707,6 @@
                                const MCInstFragment *IF,
                                const MCAsmLayout &Layout) const;
 
-  /// Compute the effective fragment size assuming it is layed out at the given
-  /// \arg SectionAddress and \arg FragmentOffset.
-  uint64_t ComputeFragmentSize(const MCFragment &F,
-                               uint64_t FragmentOffset) const;
-
   /// LayoutOnce - Perform one layout iteration and return true if any offsets
   /// were adjusted.
   bool LayoutOnce(const MCObjectWriter &Writer, MCAsmLayout &Layout);
@@ -725,6 +723,9 @@
   bool RelaxDwarfLineAddr(const MCObjectWriter &Writer, MCAsmLayout &Layout,
 			  MCDwarfLineAddrFragment &DF);
 
+  bool RelaxAlignment(const MCObjectWriter &Writer, MCAsmLayout &Layout,
+		      MCAlignFragment &DF);
+
   /// FinishLayout - Finalize a layout, including fragment lowering.
   void FinishLayout(MCAsmLayout &Layout);
 
@@ -732,6 +733,10 @@
                        MCFragment &F, const MCFixup &Fixup);
 
 public:
+  /// Compute the effective fragment size assuming it is layed out at the given
+  /// \arg SectionAddress and \arg FragmentOffset.
+  uint64_t ComputeFragmentSize(const MCFragment &F) const;
+
   /// Find the symbol which defines the atom containing the given symbol, or
   /// null if there is no such symbol.
   const MCSymbolData *getAtom(const MCSymbolData *Symbol) const;

Modified: llvm/trunk/lib/MC/MCAssembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAssembler.cpp?rev=121857&r1=121856&r2=121857&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCAssembler.cpp (original)
+++ llvm/trunk/lib/MC/MCAssembler.cpp Wed Dec 15 02:45:53 2010
@@ -74,10 +74,9 @@
   if (!isFragmentUpToDate(F))
     return;
 
-  // Otherwise, reset the last valid fragment to the predecessor of the
-  // invalidated fragment.
+  // Otherwise, reset the last valid fragment to this fragment.
   const MCSectionData &SD = *F->getParent();
-  LastValidFragment[&SD] = F->getPrevNode();
+  LastValidFragment[&SD] = F;
 }
 
 void MCAsmLayout::EnsureValid(const MCFragment *F) const {
@@ -96,12 +95,6 @@
   }
 }
 
-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!");
@@ -116,7 +109,7 @@
 uint64_t MCAsmLayout::getSectionAddressSize(const MCSectionData *SD) const {
   // The size is the last fragment's end offset.
   const MCFragment &F = SD->getFragmentList().back();
-  return getFragmentOffset(&F) + getFragmentEffectiveSize(&F);
+  return getFragmentOffset(&F) + getAssembler().ComputeFragmentSize(F);
 }
 
 uint64_t MCAsmLayout::getSectionFileSize(const MCSectionData *SD) const {
@@ -137,8 +130,7 @@
 }
 
 MCFragment::MCFragment(FragmentType _Kind, MCSectionData *_Parent)
-  : Kind(_Kind), Parent(_Parent), Atom(0), Offset(~UINT64_C(0)),
-    EffectiveSize(~UINT64_C(0))
+  : Kind(_Kind), Parent(_Parent), Atom(0), Offset(~UINT64_C(0))
 {
   if (Parent)
     Parent->getFragmentList().push_back(this);
@@ -276,8 +268,7 @@
   return IsResolved;
 }
 
-uint64_t MCAssembler::ComputeFragmentSize(const MCFragment &F,
-                                          uint64_t FragmentOffset) const {
+uint64_t MCAssembler::ComputeFragmentSize(const MCFragment &F) const {
   switch (F.getKind()) {
   case MCFragment::FT_Data:
     return cast<MCDataFragment>(F).getContents().size();
@@ -289,17 +280,8 @@
   case MCFragment::FT_LEB:
     return cast<MCLEBFragment>(F).getContents().size();
 
-  case MCFragment::FT_Align: {
-    const MCAlignFragment &AF = cast<MCAlignFragment>(F);
-
-    uint64_t Size = OffsetToAlignment(FragmentOffset, AF.getAlignment());
-
-    // Honor MaxBytesToEmit.
-    if (Size > AF.getMaxBytesToEmit())
-      return 0;
-
-    return Size;
-  }
+  case MCFragment::FT_Align:
+    return cast<MCAlignFragment>(F).getSize();
 
   case MCFragment::FT_Org:
     return cast<MCOrgFragment>(F).getSize();
@@ -327,10 +309,9 @@
   // Compute fragment offset and size.
   uint64_t Offset = 0;
   if (Prev)
-    Offset += Prev->Offset + Prev->EffectiveSize;
+    Offset += Prev->Offset + getAssembler().ComputeFragmentSize(*Prev);
 
   F->Offset = Offset;
-  F->EffectiveSize = getAssembler().ComputeFragmentSize(*F, F->Offset);
   LastValidFragment[F->getParent()] = F;
 }
 
@@ -343,7 +324,7 @@
   ++stats::EmittedFragments;
 
   // FIXME: Embed in fragments instead?
-  uint64_t FragmentSize = Layout.getFragmentEffectiveSize(&F);
+  uint64_t FragmentSize = Asm.ComputeFragmentSize(F);
   switch (F.getKind()) {
   case MCFragment::FT_Align: {
     MCAlignFragment &AF = cast<MCAlignFragment>(F);
@@ -730,6 +711,18 @@
   return OldSize != Data.size();
 }
 
+bool MCAssembler::RelaxAlignment(const MCObjectWriter &Writer,
+				 MCAsmLayout &Layout,
+				 MCAlignFragment &AF) {
+  unsigned Offset = Layout.getFragmentOffset(&AF);
+  unsigned Size = OffsetToAlignment(Offset, AF.getAlignment());
+  if (Size > AF.getMaxBytesToEmit())
+    Size = 0;
+  unsigned OldSize = AF.getSize();
+  AF.setSize(Size);
+  return OldSize != Size;
+}
+
 bool MCAssembler::LayoutOnce(const MCObjectWriter &Writer,
                              MCAsmLayout &Layout) {
   ++stats::RelaxationSteps;
@@ -747,6 +740,10 @@
       switch(it2->getKind()) {
       default:
         break;
+      case MCFragment::FT_Align:
+	relaxedFrag = RelaxAlignment(Writer, Layout,
+				     *cast<MCAlignFragment>(it2));
+	break;
       case MCFragment::FT_Inst:
         relaxedFrag = RelaxInstruction(Writer, Layout,
                                        *cast<MCInstFragment>(it2));
@@ -809,7 +806,7 @@
   }
 
   OS << "<MCFragment " << (void*) this << " LayoutOrder:" << LayoutOrder
-     << " Offset:" << Offset << " EffectiveSize:" << EffectiveSize << ">";
+     << " Offset:" << Offset << ">";
 
   switch (getKind()) {
   case MCFragment::FT_Align: {

Modified: llvm/trunk/test/MC/MachO/relax-recompute-align.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/MachO/relax-recompute-align.s?rev=121857&r1=121856&r2=121857&view=diff
==============================================================================
--- llvm/trunk/test/MC/MachO/relax-recompute-align.s (original)
+++ llvm/trunk/test/MC/MachO/relax-recompute-align.s Wed Dec 15 02:45:53 2010
@@ -3,16 +3,16 @@
 // FIXME: This is a horrible way of checking the output, we need an llvm-mc
 // based 'otool'.
 
-// FIXME: PR8467.
-// There is an unnecessary relaxation here. After the first jmp slides,
-// the .align size could be recomputed so that the second jump will be in range
-// for a 1-byte jump. For performance reasons, this is not currently done.
+// This is a case where llvm-mc computes a better layout than Darwin 'as'. This
+// issue is that after the first jmp slides, the .align size must be
+// recomputed -- otherwise the second jump will appear to be out-of-range for a
+// 1-byte jump.
 
 // CHECK:  # Section 0
 // CHECK: (('section_name', '__text\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
 // CHECK:  ('segment_name', '__TEXT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00')
 // CHECK:  ('address', 0)
-// CHECK:  ('size', 322)
+// CHECK:  ('size', 306)
 // CHECK:  ('offset', 324)
 // CHECK:  ('alignment', 4)
 // CHECK:  ('reloc_offset', 0)





More information about the llvm-commits mailing list