Remember the contents of leb and dwarfline fragments when relaxing. This avoids
authorRafael Espindola <rafael.espindola@gmail.com>
Sat, 4 Dec 2010 21:58:52 +0000 (21:58 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Sat, 4 Dec 2010 21:58:52 +0000 (21:58 +0000)
having to evaluate the expression again when writing.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@120920 91177308-0d34-0410-b5e6-96231b3b80d8

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

index 4f3223f5db306240bfd2b3c109fc68ae51215af0..0fb3a8ce2d075de56efe5308dca39bc168ff5c1e 100644 (file)
@@ -352,13 +352,11 @@ class MCLEBFragment : public MCFragment {
   /// IsSigned - True if this is a sleb128, false if uleb128.
   bool IsSigned;
 
-  /// Size - The current size estimate.
-  uint64_t Size;
-
+  SmallString<8> Contents;
 public:
   MCLEBFragment(const MCExpr &Value_, bool IsSigned_, MCSectionData *SD)
     : MCFragment(FT_LEB, SD),
-      Value(&Value_), IsSigned(IsSigned_), Size(1) {}
+      Value(&Value_), IsSigned(IsSigned_) { Contents.push_back(0); }
 
   /// @name Accessors
   /// @{
@@ -367,9 +365,8 @@ public:
 
   bool isSigned() const { return IsSigned; }
 
-  uint64_t getSize() const { return Size; }
-
-  void setSize(uint64_t Size_) { Size = Size_; }
+  SmallString<8> &getContents() { return Contents; }
+  const SmallString<8> &getContents() const { return Contents; }
 
   /// @}
 
@@ -388,14 +385,13 @@ class MCDwarfLineAddrFragment : public MCFragment {
   /// make up the address delta between two .loc dwarf directives.
   const MCExpr *AddrDelta;
 
-  /// Size - The current size estimate.
-  uint64_t Size;
+  SmallString<8> Contents;
 
 public:
   MCDwarfLineAddrFragment(int64_t _LineDelta, const MCExpr &_AddrDelta,
                       MCSectionData *SD = 0)
     : MCFragment(FT_Dwarf, SD),
-      LineDelta(_LineDelta), AddrDelta(&_AddrDelta), Size(1) {}
+      LineDelta(_LineDelta), AddrDelta(&_AddrDelta) { Contents.push_back(0); }
 
   /// @name Accessors
   /// @{
@@ -404,9 +400,8 @@ public:
 
   const MCExpr &getAddrDelta() const { return *AddrDelta; }
 
-  uint64_t getSize() const { return Size; }
-
-  void setSize(uint64_t Size_) { Size = Size_; }
+  SmallString<8> &getContents() { return Contents; }
+  const SmallString<8> &getContents() const { return Contents; }
 
   /// @}
 
index e9fc0cf87698546fc03870e062602825c9866f58..46177be2303adb488866e8315ca0b71ac3fe8777 100644 (file)
@@ -220,9 +220,6 @@ namespace llvm {
     static void Emit(MCStreamer *MCOS,
                      int64_t LineDelta,uint64_t AddrDelta);
 
-    /// Utility function to compute the size of the encoding.
-    static uint64_t ComputeSize(int64_t LineDelta, uint64_t AddrDelta);
-
     /// Utility function to write the encoding to an object writer.
     static void Write(MCObjectWriter *OW,
                       int64_t LineDelta, uint64_t AddrDelta);
index 86bdca1c21fbb6f520b06cdd8660aa2ea0b32ba5..451ad1f4e84ce96ed85286d74c84b34fc46c2fb2 100644 (file)
@@ -348,7 +348,7 @@ uint64_t MCAssembler::ComputeFragmentSize(const MCFragment &F,
     return cast<MCInstFragment>(F).getInstSize();
 
   case MCFragment::FT_LEB:
-    return cast<MCLEBFragment>(F).getSize();
+    return cast<MCLEBFragment>(F).getContents().size();
 
   case MCFragment::FT_Align: {
     const MCAlignFragment &AF = cast<MCAlignFragment>(F);
@@ -370,7 +370,7 @@ uint64_t MCAssembler::ComputeFragmentSize(const MCFragment &F,
     return cast<MCOrgFragment>(F).getSize();
 
   case MCFragment::FT_Dwarf:
-    return cast<MCDwarfLineAddrFragment>(F).getSize();
+    return cast<MCDwarfLineAddrFragment>(F).getContents().size();
   }
 
   assert(0 && "invalid fragment kind");
@@ -522,20 +522,7 @@ static void WriteFragmentData(const MCAssembler &Asm, const MCAsmLayout &Layout,
 
   case MCFragment::FT_LEB: {
     MCLEBFragment &LF = cast<MCLEBFragment>(F);
-
-    // FIXME: It is probably better if we don't call EvaluateAsAbsolute in
-    // here.
-    int64_t Value;
-    bool IsAbs = LF.getValue().EvaluateAsAbsolute(Value, &Layout);
-    assert(IsAbs);
-    (void) IsAbs;
-    SmallString<32> Tmp;
-    raw_svector_ostream OSE(Tmp);
-    if (LF.isSigned())
-      MCObjectWriter::EncodeSLEB128(Value, OSE);
-    else
-      MCObjectWriter::EncodeULEB128(Value, OSE);
-    OW->WriteBytes(OSE.str());
+    OW->WriteBytes(LF.getContents().str());
     break;
   }
 
@@ -550,15 +537,7 @@ static void WriteFragmentData(const MCAssembler &Asm, const MCAsmLayout &Layout,
 
   case MCFragment::FT_Dwarf: {
     const MCDwarfLineAddrFragment &OF = cast<MCDwarfLineAddrFragment>(F);
-
-    // The AddrDelta is really unsigned and it can only increase.
-    int64_t AddrDelta;
-    OF.getAddrDelta().EvaluateAsAbsolute(AddrDelta, &Layout);
-
-    int64_t LineDelta;
-    LineDelta = OF.getLineDelta();
-
-    MCDwarfLineAddr::Write(OW, LineDelta, (uint64_t)AddrDelta);
+    OW->WriteBytes(OF.getContents().str());
     break;
   }
   }
@@ -830,29 +809,34 @@ bool MCAssembler::RelaxOrg(const MCObjectWriter &Writer,
 bool MCAssembler::RelaxLEB(const MCObjectWriter &Writer,
                            MCAsmLayout &Layout,
                            MCLEBFragment &LF) {
-  int64_t Value;
+  int64_t Value = 0;
+  uint64_t OldSize = LF.getContents().size();
   LF.getValue().EvaluateAsAbsolute(Value, &Layout);
-  SmallString<32> Tmp;
-  raw_svector_ostream OSE(Tmp);
+  SmallString<8> &Data = LF.getContents();
+  Data.clear();
+  raw_svector_ostream OSE(Data);
   if (LF.isSigned())
     MCObjectWriter::EncodeSLEB128(Value, OSE);
   else
     MCObjectWriter::EncodeULEB128(Value, OSE);
-  uint64_t OldSize = LF.getSize();
-  LF.setSize(OSE.GetNumBytesInBuffer());
-  return OldSize != LF.getSize();
+  OSE.flush();
+  return OldSize != LF.getContents().size();
 }
 
 bool MCAssembler::RelaxDwarfLineAddr(const MCObjectWriter &Writer,
                                     MCAsmLayout &Layout,
                                     MCDwarfLineAddrFragment &DF) {
-  int64_t AddrDelta;
+  int64_t AddrDelta = 0;
+  uint64_t OldSize = DF.getContents().size();
   DF.getAddrDelta().EvaluateAsAbsolute(AddrDelta, &Layout);
   int64_t LineDelta;
   LineDelta = DF.getLineDelta();
-  uint64_t OldSize = DF.getSize();
-  DF.setSize(MCDwarfLineAddr::ComputeSize(LineDelta, AddrDelta));
-  return OldSize != DF.getSize();  
+  SmallString<8> &Data = DF.getContents();
+  Data.clear();
+  raw_svector_ostream OSE(Data);
+  MCDwarfLineAddr::Encode(LineDelta, AddrDelta, OSE);
+  OSE.flush();
+  return OldSize != Data.size();
 }
 
 bool MCAssembler::LayoutOnce(const MCObjectWriter &Writer,
index 1b1d50970420d6338d98a47408110cee682f76be..53731dca7eb173f6e518db0dab59240b6a1cdcf0 100644 (file)
@@ -320,14 +320,6 @@ void MCDwarfFileTable::Emit(MCStreamer *MCOS,
   MCOS->EmitLabel(LineEndSym);
 }
 
-/// Utility function to compute the size of the encoding.
-uint64_t MCDwarfLineAddr::ComputeSize(int64_t LineDelta, uint64_t AddrDelta) {
-  SmallString<256> Tmp;
-  raw_svector_ostream OS(Tmp);
-  MCDwarfLineAddr::Encode(LineDelta, AddrDelta, OS);
-  return OS.GetNumBytesInBuffer();
-}
-
 /// Utility function to write the encoding to an object writer.
 void MCDwarfLineAddr::Write(MCObjectWriter *OW, int64_t LineDelta,
                             uint64_t AddrDelta) {