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

Daniel Dunbar daniel at zuster.org
Mon Mar 22 16:16:48 PDT 2010


Author: ddunbar
Date: Mon Mar 22 18:16:48 2010
New Revision: 99229

URL: http://llvm.org/viewvc/llvm-project?rev=99229&view=rev
Log:
MC: Add MCInstFragment, not used yet.

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

Modified: llvm/trunk/include/llvm/MC/MCAssembler.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCAssembler.h?rev=99229&r1=99228&r2=99229&view=diff
==============================================================================
--- llvm/trunk/include/llvm/MC/MCAssembler.h (original)
+++ llvm/trunk/include/llvm/MC/MCAssembler.h Mon Mar 22 18:16:48 2010
@@ -16,6 +16,7 @@
 #include "llvm/ADT/ilist_node.h"
 #include "llvm/Support/Casting.h"
 #include "llvm/MC/MCFixup.h"
+#include "llvm/MC/MCInst.h"
 #include "llvm/System/DataTypes.h"
 #include <vector> // FIXME: Shouldn't be needed.
 
@@ -37,6 +38,8 @@
 /// MCAsmFixup - Represent a fixed size region of bytes inside some fragment
 /// which needs to be rewritten. This region will either be rewritten by the
 /// assembler or cause a relocation entry to be generated.
+//
+// FIXME: This should probably just be merged with MCFixup.
 class MCAsmFixup {
 public:
   /// Offset - The offset inside the fragment which needs to be rewritten.
@@ -59,9 +62,10 @@
 
 public:
   enum FragmentType {
-    FT_Data,
     FT_Align,
+    FT_Data,
     FT_Fill,
+    FT_Inst,
     FT_Org,
     FT_ZeroFill
   };
@@ -145,7 +149,6 @@
   const SmallString<32> &getContents() const { return Contents; }
 
   /// @}
-
   /// @name Fixup Access
   /// @{
 
@@ -177,6 +180,39 @@
   virtual void dump();
 };
 
+class MCInstFragment : public MCFragment {
+  /// Inst - The instruction this is a fragment for.
+  MCInst Inst;
+
+  /// InstSize - The size of the currently encoded instruction.
+  unsigned InstSize;
+
+public:
+  MCInstFragment(MCInst _Inst, unsigned _InstSize, MCSectionData *SD = 0)
+    : MCFragment(FT_Inst, SD), Inst(_Inst), InstSize(_InstSize) {}
+
+  /// @name Accessors
+  /// @{
+
+  unsigned getInstSize() const { return InstSize; }
+
+  const MCInst &getInst() const { return Inst; }
+
+  void setInst(MCInst Inst, unsigned InstSize) {
+    this->Inst = Inst;
+    this->InstSize = InstSize;
+  }
+
+  /// @}
+
+  static bool classof(const MCFragment *F) {
+    return F->getKind() == MCFragment::FT_Inst;
+  }
+  static bool classof(const MCInstFragment *) { return true; }
+
+  virtual void dump();
+};
+
 class MCAlignFragment : public MCFragment {
   /// Alignment - The alignment to ensure, in bytes.
   unsigned Alignment;
@@ -623,6 +659,9 @@
   /// were adjusted.
   bool LayoutOnce(MCAsmLayout &Layout);
 
+  /// FinishLayout - Finalize a layout, including fragment lowering.
+  void FinishLayout(MCAsmLayout &Layout);
+
 public:
   /// Find the symbol which defines the atom containing given address, inside
   /// the given section, or null if there is no such symbol.

Modified: llvm/trunk/lib/MC/MCAssembler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAssembler.cpp?rev=99229&r1=99228&r2=99229&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCAssembler.cpp (original)
+++ llvm/trunk/lib/MC/MCAssembler.cpp Mon Mar 22 18:16:48 2010
@@ -327,6 +327,10 @@
       break;
     }
 
+    case MCFragment::FT_Inst:
+      F.setFileSize(cast<MCInstFragment>(F).getInstSize());
+      break;
+
     case MCFragment::FT_Org: {
       MCOrgFragment &OF = cast<MCOrgFragment>(F);
 
@@ -471,7 +475,9 @@
   }
 
   case MCFragment::FT_Data: {
-    OW->WriteBytes(cast<MCDataFragment>(F).getContents().str());
+    MCDataFragment &DF = cast<MCDataFragment>(F);
+    assert(DF.getFileSize() == DF.getContents().size() && "Invalid size!");
+    OW->WriteBytes(DF.getContents().str());
     break;
   }
 
@@ -490,6 +496,10 @@
     break;
   }
 
+  case MCFragment::FT_Inst:
+    llvm_unreachable("unexpected inst fragment after lowering");
+    break;
+
   case MCFragment::FT_Org: {
     MCOrgFragment &OF = cast<MCOrgFragment>(F);
 
@@ -541,7 +551,14 @@
     continue;
 
   DEBUG_WITH_TYPE("mc-dump", {
-      llvm::errs() << "assembler backend - post-layout\n--\n";
+      llvm::errs() << "assembler backend - post-relaxation\n--\n";
+      dump(); });
+
+  // Finalize the layout, including fragment lowering.
+  FinishLayout(Layout);
+
+  DEBUG_WITH_TYPE("mc-dump", {
+      llvm::errs() << "assembler backend - final-layout\n--\n";
       dump(); });
 
   llvm::OwningPtr<MCObjectWriter> Writer(getBackend().createObjectWriter(OS));
@@ -722,8 +739,8 @@
 
         // Restart layout.
         //
-        // FIXME: This is O(N^2), but will be eliminated once we have a smart
-        // MCAsmLayout object.
+        // FIXME-PERF: This is O(N^2), but will be eliminated once we have a
+        // smart MCAsmLayout object.
         return true;
       }
     }
@@ -732,6 +749,54 @@
   return false;
 }
 
+void MCAssembler::FinishLayout(MCAsmLayout &Layout) {
+  // Lower out any instruction fragments, to simplify the fixup application and
+  // output.
+  //
+  // FIXME-PERF: We don't have to do this, but the assumption is that it is
+  // 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;
+
+    for (MCSectionData::iterator it2 = SD.begin(),
+           ie2 = SD.end(); it2 != ie2; ++it2) {
+      MCInstFragment *IF = dyn_cast<MCInstFragment>(it2);
+      if (!IF)
+        continue;
+
+      // Create a new data fragment for the instruction.
+      //
+      // FIXME: Reuse previous data fragment if possible.
+      MCDataFragment *DF = new MCDataFragment();
+      SD.getFragmentList().insert(it2, DF);
+
+      // Update the data fragments layout data.
+      DF->setOffset(IF->getOffset());
+      DF->setFileSize(IF->getInstSize());
+
+      // Encode the final instruction.
+      SmallVector<MCFixup, 4> Fixups;
+      raw_svector_ostream VecOS(DF->getContents());
+      getEmitter().EncodeInstruction(IF->getInst(), VecOS, Fixups);
+
+      // Copy over the fixups.
+      //
+      // FIXME-PERF: Encode fixups directly into the data fragment as well.
+      for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
+        MCFixup &F = Fixups[i];
+        DF->addFixup(MCAsmFixup(DF->getContents().size()+F.getOffset(),
+                                *F.getValue(), F.getKind()));
+      }
+
+      // Delete the instruction fragment and update the iterator.
+      SD.getFragmentList().erase(IF);
+      it2 = DF;
+    }
+  }
+}
+
 // Debugging methods
 
 namespace llvm {
@@ -800,6 +865,17 @@
      << " Count:" << getCount() << ">";
 }
 
+void MCInstFragment::dump() {
+  raw_ostream &OS = llvm::errs();
+
+  OS << "<MCInstFragment ";
+  this->MCFragment::dump();
+  OS << "\n       ";
+  OS << " Inst:";
+  getInst().dump_pretty(OS);
+  OS << ">";
+}
+
 void MCOrgFragment::dump() {
   raw_ostream &OS = llvm::errs();
 

Modified: llvm/trunk/lib/MC/MCMachOStreamer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCMachOStreamer.cpp?rev=99229&r1=99228&r2=99229&view=diff
==============================================================================
--- llvm/trunk/lib/MC/MCMachOStreamer.cpp (original)
+++ llvm/trunk/lib/MC/MCMachOStreamer.cpp Mon Mar 22 18:16:48 2010
@@ -375,6 +375,9 @@
 
   CurSectionData->setHasInstructions(true);
 
+  // FIXME-PERF: Common case is that we don't need to relax, encode directly
+  // onto the data fragments buffers.
+
   SmallVector<MCFixup, 4> Fixups;
   SmallString<256> Code;
   raw_svector_ostream VecOS(Code);





More information about the llvm-commits mailing list