MC: Add TargetAsmBackend::MayNeedRelaxation, for checking whether a particular instru...
authorDaniel Dunbar <daniel@zuster.org>
Tue, 23 Mar 2010 03:13:05 +0000 (03:13 +0000)
committerDaniel Dunbar <daniel@zuster.org>
Tue, 23 Mar 2010 03:13:05 +0000 (03:13 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@99249 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/MC/MCAssembler.h
include/llvm/Target/TargetAsmBackend.h
lib/MC/MCAssembler.cpp
lib/MC/MCMachOStreamer.cpp
lib/Target/X86/X86AsmBackend.cpp

index d7f1acea35e66c9594b3d8c58c0944d4497d58e8..d14122bf74c8c8e3e34ce441f386c3a260b3942b 100644 (file)
@@ -679,6 +679,10 @@ private:
   bool FixupNeedsRelaxation(const MCAsmFixup &Fixup, const MCFragment *DF,
                             const MCAsmLayout &Layout) const;
 
+  /// Check whether the given fragment needs relaxation.
+  bool FragmentNeedsRelaxation(const MCInstFragment *IF,
+                               const MCAsmLayout &Layout) const;
+
   /// LayoutSection - Assign offsets and sizes to the fragments in the section
   /// \arg SD, and update the section size. The section file offset should
   /// already have been computed.
index 16f33c32f484dc9bc32da99d8456d15ac6d17322..f350ecc410ac24c30c6c58d7929b23f2383e3872 100644 (file)
@@ -19,6 +19,8 @@ class MCInst;
 class MCInstFragment;
 class MCObjectWriter;
 class MCSection;
+template<typename T>
+class SmallVectorImpl;
 class Target;
 class raw_ostream;
 
@@ -98,6 +100,15 @@ public:
   virtual void ApplyFixup(const MCAsmFixup &Fixup, MCDataFragment &Fragment,
                           uint64_t Value) const = 0;
 
+  /// MayNeedRelaxation - Check whether the given instruction may need
+  /// relaxation.
+  ///
+  /// \arg Inst - The instruction to test.
+  /// \arg Fixups - The actual fixups this instruction encoded to, for potential
+  /// use by the target backend.
+  virtual bool MayNeedRelaxation(const MCInst &Inst,
+                           const SmallVectorImpl<MCAsmFixup> &Fixups) const = 0;
+
   /// RelaxInstruction - Relax the instruction in the given fragment to the next
   /// wider instruction.
   virtual void RelaxInstruction(const MCInstFragment *IF,
index 7672528524ba8d413b0e2d672941af8e5ad122e4..031820d528645007a89db23ba2f47575776ddaaf 100644 (file)
@@ -715,7 +715,7 @@ void MCAssembler::FinishLayout(MCAsmLayout &Layout) {
 
       // Create a new data fragment for the instruction.
       //
-      // FIXME: Reuse previous data fragment if possible.
+      // FIXME-PERF: Reuse previous data fragment if possible.
       MCDataFragment *DF = new MCDataFragment();
       SD.getFragmentList().insert(it2, DF);
 
index a52d962c9a40f19babe45cdbe8b74f785072d83c..2a1aa273014acb82f8c94105c3cb19b5e6988b2a 100644 (file)
@@ -383,12 +383,19 @@ void MCMachOStreamer::EmitInstruction(const MCInst &Inst) {
   Assembler.getEmitter().EncodeInstruction(Inst, VecOS, Fixups);
   VecOS.flush();
 
-  // Add the fixups and data.
-  MCDataFragment *DF = getOrCreateDataFragment();
+  // FIXME: Eliminate this copy.
+  SmallVector<MCAsmFixup, 4> AsmFixups;
   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()));
+    AsmFixups.push_back(MCAsmFixup(F.getOffset(), *F.getValue(),
+                                   F.getKind()));
+  }
+
+  // Add the fixups and data.
+  MCDataFragment *DF = getOrCreateDataFragment();
+  for (unsigned i = 0, e = AsmFixups.size(); i != e; ++i) {
+    AsmFixups[i].Offset += DF->getContents().size();
+    DF->addFixup(AsmFixups[i]);
   }
   DF->getContents().append(Code.begin(), Code.end());
 }
index 3e4e2b5ae2fa7fcfb76339397f094a77260c64d8..8e2928c3b7134bc0e64555d6923187cd1b795202 100644 (file)
@@ -12,6 +12,7 @@
 #include "X86FixupKinds.h"
 #include "llvm/ADT/Twine.h"
 #include "llvm/MC/MCAssembler.h"
+#include "llvm/MC/MCObjectWriter.h"
 #include "llvm/MC/MCSectionELF.h"
 #include "llvm/MC/MCSectionMachO.h"
 #include "llvm/MC/MachObjectWriter.h"
@@ -52,6 +53,9 @@ public:
       DF.getContents()[Fixup.Offset + i] = uint8_t(Value >> (i * 8));
   }
 
+  bool MayNeedRelaxation(const MCInst &Inst,
+                         const SmallVectorImpl<MCAsmFixup> &Fixups) const;
+
   void RelaxInstruction(const MCInstFragment *IF, MCInst &Res) const;
 
   bool WriteNopData(uint64_t Count, MCObjectWriter *OW) const;
@@ -82,6 +86,20 @@ static unsigned getRelaxedOpcode(unsigned Op) {
   }
 }
 
+bool X86AsmBackend::MayNeedRelaxation(const MCInst &Inst,
+                              const SmallVectorImpl<MCAsmFixup> &Fixups) const {
+  // Check for a 1byte pcrel fixup, and enforce that we would know how to relax
+  // this instruction.
+  for (unsigned i = 0, e = Fixups.size(); i != e; ++i) {
+    if (unsigned(Fixups[i].Kind) == X86::reloc_pcrel_1byte) {
+      assert(getRelaxedOpcode(Inst.getOpcode()) != Inst.getOpcode());
+      return true;
+    }
+  }
+
+  return false;
+}
+
 // FIXME: Can tblgen help at all here to verify there aren't other instructions
 // we can relax?
 void X86AsmBackend::RelaxInstruction(const MCInstFragment *IF,