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

Daniel Dunbar daniel at zuster.org
Thu Feb 11 13:29:46 PST 2010


Author: ddunbar
Date: Thu Feb 11 15:29:46 2010
New Revision: 95926

URL: http://llvm.org/viewvc/llvm-project?rev=95926&view=rev
Log:
MC: Move assembler-backend's fixup list into the fragment.

Modified:
    llvm/trunk/include/llvm/MC/MCAssembler.h
    llvm/trunk/lib/MC/MCAssembler.cpp

Modified: llvm/trunk/include/llvm/MC/MCAssembler.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCAssembler.h?rev=95926&r1=95925&r2=95926&view=diff

==============================================================================
--- llvm/trunk/include/llvm/MC/MCAssembler.h (original)
+++ llvm/trunk/include/llvm/MC/MCAssembler.h Thu Feb 11 15:29:46 2010
@@ -31,9 +31,6 @@
 /// which needs to be rewritten. This region will either be rewritten by the
 /// assembler or cause a relocation entry to be generated.
 struct MCAsmFixup {
-  /// Fragment - The fragment containing the fixup.
-  MCFragment *Fragment;
-  
   /// Offset - The offset inside the fragment which needs to be rewritten.
   uint64_t Offset;
 
@@ -49,10 +46,8 @@
   uint64_t FixedValue;
 
 public:
-  MCAsmFixup(MCFragment &_Fragment, uint64_t _Offset, const MCExpr &_Value,
-             unsigned _Size) 
-    : Fragment(&_Fragment), Offset(_Offset), Value(&_Value), Size(_Size),
-      FixedValue(0) {}
+  MCAsmFixup(uint64_t _Offset, const MCExpr &_Value, unsigned _Size) 
+    : Offset(_Offset), Value(&_Value), Size(_Size), FixedValue(0) {}
 };
 
 class MCFragment : public ilist_node<MCFragment> {
@@ -60,6 +55,10 @@
   void operator=(const MCFragment&); // DO NOT IMPLEMENT
 
 public:
+  typedef std::vector<MCAsmFixup>::const_iterator const_fixup_iterator;
+  typedef std::vector<MCAsmFixup>::iterator fixup_iterator;
+
+public:
   enum FragmentType {
     FT_Data,
     FT_Align,
@@ -86,6 +85,11 @@
   /// FileSize - The file size of this section. This is ~0 until initialized.
   uint64_t FileSize;
 
+  /// Fixups - The list of fixups in this fragment.
+  //
+  // FIXME: This should be sunk into MCDataFragment.
+  std::vector<MCAsmFixup> Fixups;
+
   /// @}
 
 protected:
@@ -107,6 +111,39 @@
     return 0;
   }
 
+  /// @name Fixup Access
+  /// @{
+
+  /// LookupFixup - Look up the fixup for the given \arg Fragment and \arg
+  /// Offset.
+  ///
+  /// If multiple fixups exist for the same fragment and offset it is undefined
+  /// which one is returned.
+  //
+  // FIXME: This isn't horribly slow in practice, but there are much nicer
+  // solutions to applying the fixups. This will be fixed by sinking fixups into
+  // data fragments exclusively.
+  const MCAsmFixup *LookupFixup(uint64_t Offset) const {
+    for (unsigned i = 0, e = Fixups.size(); i != e; ++i)
+      if (Fixups[i].Offset == Offset)
+        return &Fixups[i];
+    return 0;
+  }
+
+  std::vector<MCAsmFixup> &getFixups() {
+    return Fixups;
+  }
+
+  fixup_iterator fixup_begin() {
+    return Fixups.begin();
+  }
+
+  fixup_iterator fixup_end() {
+    return Fixups.end();
+  }
+
+  size_t fixup_size() const { return Fixups.size(); }
+
   /// @name Assembler Backend Support
   /// @{
   //
@@ -313,14 +350,13 @@
   void operator=(const MCSectionData&); // DO NOT IMPLEMENT
 
 public:
-
   typedef iplist<MCFragment> FragmentListType;
 
   typedef FragmentListType::const_iterator const_iterator;
   typedef FragmentListType::iterator iterator;
 
-  typedef std::vector<MCAsmFixup>::const_iterator const_fixup_iterator;
-  typedef std::vector<MCAsmFixup>::iterator fixup_iterator;
+  typedef FragmentListType::const_reverse_iterator const_reverse_iterator;
+  typedef FragmentListType::reverse_iterator reverse_iterator;
 
 private:
   iplist<MCFragment> Fragments;
@@ -345,12 +381,6 @@
   /// initialized.
   uint64_t FileSize;
 
-  /// LastFixupLookup - Cache for the last looked up fixup.
-  mutable unsigned LastFixupLookup;
-
-  /// Fixups - The list of fixups in this section.
-  std::vector<MCAsmFixup> Fixups;
-
   /// HasInstructions - Whether this section has had instructions emitted into
   /// it.
   unsigned HasInstructions : 1;
@@ -379,27 +409,15 @@
   iterator end() { return Fragments.end(); }
   const_iterator end() const { return Fragments.end(); }
 
-  size_t size() const { return Fragments.size(); }
-
-  bool empty() const { return Fragments.empty(); }
+  reverse_iterator rbegin() { return Fragments.rbegin(); }
+  const_reverse_iterator rbegin() const { return Fragments.rbegin(); }
 
-  /// @}
-  /// @name Fixup Access
-  /// @{
+  reverse_iterator rend() { return Fragments.rend(); }
+  const_reverse_iterator rend() const { return Fragments.rend(); }
 
-  std::vector<MCAsmFixup> &getFixups() {
-    return Fixups;
-  }
-
-  fixup_iterator fixup_begin() {
-    return Fixups.begin();
-  }
-
-  fixup_iterator fixup_end() {
-    return Fixups.end();
-  }
+  size_t size() const { return Fragments.size(); }
 
-  size_t fixup_size() const { return Fixups.size(); }
+  bool empty() const { return Fragments.empty(); }
 
   /// @}
   /// @name Assembler Backend Support
@@ -407,17 +425,6 @@
   //
   // FIXME: This could all be kept private to the assembler implementation.
 
-  /// LookupFixup - Look up the fixup for the given \arg Fragment and \arg
-  /// Offset.
-  ///
-  /// If multiple fixups exist for the same fragment and offset it is undefined
-  /// which one is returned.
-  //
-  // FIXME: This isn't horribly slow in practice, but there are much nicer
-  // solutions to applying the fixups.
-  const MCAsmFixup *LookupFixup(const MCFragment *Fragment,
-                                uint64_t Offset) const;
-
   uint64_t getAddress() const { 
     assert(Address != ~UINT64_C(0) && "Address not set!");
     return Address;

Modified: llvm/trunk/lib/MC/MCAssembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAssembler.cpp?rev=95926&r1=95925&r2=95926&view=diff

==============================================================================
--- llvm/trunk/lib/MC/MCAssembler.cpp (original)
+++ llvm/trunk/lib/MC/MCAssembler.cpp Thu Feb 11 15:29:46 2010
@@ -402,12 +402,12 @@
     uint32_t Word0;
     uint32_t Word1;
   };
-  void ComputeScatteredRelocationInfo(MCAssembler &Asm,
+  void ComputeScatteredRelocationInfo(MCAssembler &Asm, MCFragment &Fragment,
                                       MCAsmFixup &Fixup,
                                       const MCValue &Target,
                              DenseMap<const MCSymbol*,MCSymbolData*> &SymbolMap,
                                      std::vector<MachRelocationEntry> &Relocs) {
-    uint32_t Address = Fixup.Fragment->getOffset() + Fixup.Offset;
+    uint32_t Address = Fragment.getOffset() + Fixup.Offset;
     unsigned IsPCRel = 0;
     unsigned Type = RIT_Vanilla;
 
@@ -453,7 +453,7 @@
     }
   }
 
-  void ComputeRelocationInfo(MCAssembler &Asm,
+  void ComputeRelocationInfo(MCAssembler &Asm, MCFragment &Fragment,
                              MCAsmFixup &Fixup,
                              DenseMap<const MCSymbol*,MCSymbolData*> &SymbolMap,
                              std::vector<MachRelocationEntry> &Relocs) {
@@ -466,11 +466,11 @@
     if (Target.getSymB() ||
         (Target.getSymA() && !Target.getSymA()->isUndefined() &&
          Target.getConstant()))
-      return ComputeScatteredRelocationInfo(Asm, Fixup, Target,
+      return ComputeScatteredRelocationInfo(Asm, Fragment, Fixup, Target,
                                             SymbolMap, Relocs);
 
     // See <reloc.h>.
-    uint32_t Address = Fixup.Fragment->getOffset() + Fixup.Offset;
+    uint32_t Address = Fragment.getOffset() + Fixup.Offset;
     uint32_t Value = 0;
     unsigned Index = 0;
     unsigned IsPCRel = 0;
@@ -766,17 +766,19 @@
     // is written.
     std::vector<MachRelocationEntry> RelocInfos;
     uint64_t RelocTableEnd = SectionDataStart + SectionDataFileSize;
-    for (MCAssembler::iterator it = Asm.begin(), ie = Asm.end(); it != ie;
-         ++it) {
+    for (MCAssembler::iterator it = Asm.begin(),
+           ie = Asm.end(); it != ie; ++it) {
       MCSectionData &SD = *it;
 
       // The assembler writes relocations in the reverse order they were seen.
       //
       // FIXME: It is probably more complicated than this.
       unsigned NumRelocsStart = RelocInfos.size();
-      for (unsigned i = 0, e = SD.fixup_size(); i != e; ++i)
-        ComputeRelocationInfo(Asm, SD.getFixups()[e - i - 1], SymbolMap,
-                              RelocInfos);
+      for (MCSectionData::reverse_iterator it2 = SD.rbegin(),
+             ie2 = SD.rend(); it2 != ie2; ++it2)
+        for (unsigned i = 0, e = it2->fixup_size(); i != e; ++i)
+          ComputeRelocationInfo(Asm, *it2, it2->getFixups()[e - i - 1],
+                                SymbolMap, RelocInfos);
 
       unsigned NumRelocs = RelocInfos.size() - NumRelocsStart;
       uint64_t SectionStart = SectionDataStart + SD.getAddress();
@@ -905,35 +907,12 @@
     Address(~UINT64_C(0)),
     Size(~UINT64_C(0)),
     FileSize(~UINT64_C(0)),
-    LastFixupLookup(~0),
     HasInstructions(false)
 {
   if (A)
     A->getSectionList().push_back(this);
 }
 
-const MCAsmFixup *MCSectionData::LookupFixup(const MCFragment *Fragment,
-                                             uint64_t Offset) const {
-  // Use a one level cache to turn the common case of accessing the fixups in
-  // order into O(1) instead of O(N).
-  unsigned i = LastFixupLookup, Count = Fixups.size(), End = Fixups.size();
-  if (i >= End)
-    i = 0;
-  while (Count--) {
-    const MCAsmFixup &F = Fixups[i];
-    if (F.Fragment == Fragment && F.Offset == Offset) {
-      LastFixupLookup = i;
-      return &F;
-    }
-
-    ++i;
-    if (i == End)
-      i = 0;
-  }
-
-  return 0;
-}
-
 /* *** */
 
 MCSymbolData::MCSymbolData() : Symbol(0) {}
@@ -997,10 +976,13 @@
         break;
 
       // Otherwise, add fixups for the values.
-      for (uint64_t i = 0, e = FF.getCount(); i != e; ++i) {
-        MCAsmFixup Fix(F, i*FF.getValueSize(), FF.getValue(),FF.getValueSize());
-        SD.getFixups().push_back(Fix);
-      }
+      //
+      // FIXME: What we want to do here is lower this to a data fragment once we
+      // realize it will need relocations. This means that the only place we
+      // need to worry about relocations and fixing is on data fragments.
+      for (uint64_t i = 0, e = FF.getCount(); i != e; ++i)
+        FF.getFixups().push_back(MCAsmFixup(i*FF.getValueSize(), FF.getValue(),
+                                            FF.getValueSize()));
       break;
     }
 
@@ -1105,9 +1087,9 @@
       if (!Target.isAbsolute()) {
         // Find the fixup.
         //
-        // FIXME: Find a better way to write in the fixes.
-        const MCAsmFixup *Fixup =
-          F.getParent()->LookupFixup(&F, i * FF.getValueSize());
+        // FIXME: Find a better way to write in the fixes (move to
+        // MCDataFragment).
+        const MCAsmFixup *Fixup = FF.LookupFixup(i * FF.getValueSize());
         assert(Fixup && "Missing fixup for fill value!");
         Value = Fixup->FixedValue;
       }





More information about the llvm-commits mailing list