Generalize emitAbsoluteSymbolDiff.
authorRafael Espindola <rafael.espindola@gmail.com>
Thu, 11 Jun 2015 18:58:08 +0000 (18:58 +0000)
committerRafael Espindola <rafael.espindola@gmail.com>
Thu, 11 Jun 2015 18:58:08 +0000 (18:58 +0000)
This makes emitAbsoluteSymbolDiff always succeed and moves logic from the asm
printer to it.

The object one now also works on ELF. If two symbols are in the same fragment,
we will never move them apart.

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

include/llvm/MC/MCObjectStreamer.h
include/llvm/MC/MCStreamer.h
lib/CodeGen/AsmPrinter/AsmPrinter.cpp
lib/MC/MCObjectStreamer.cpp
lib/MC/MCStreamer.cpp

index 462b3b484c58b9dc3b0015e2d7cdf1054e15e642..131da07c23a876d8fa52fdf20c3e46cfb1770b46 100644 (file)
@@ -136,7 +136,7 @@ public:
   ///
   /// \pre Offset of \c Hi is greater than the offset \c Lo.
   /// \return true on success.
-  bool emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo,
+  void emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo,
                               unsigned Size) override;
 
   bool mayHaveInstructions(MCSection &Sec) const override;
index 628fb768856ebad0322dc6aaafc561ef236717e0..4dd53df25ec27b87702dd24a1e56e3c7bd16167b 100644 (file)
@@ -636,14 +636,12 @@ public:
                                      unsigned Isa, unsigned Discriminator,
                                      StringRef FileName);
 
-  /// Emit the absolute difference between two symbols if possible.
+  /// Emit the absolute difference between two symbols.
   ///
   /// \pre Offset of \c Hi is greater than the offset \c Lo.
   /// \return true on success.
-  virtual bool emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo,
-                                      unsigned Size) {
-    return false;
-  }
+  virtual void emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo,
+                                      unsigned Size);
 
   virtual MCSymbol *getDwarfLineTableSymbol(unsigned CUID);
   virtual void EmitCFISections(bool EH, bool Debug);
index 04b936afa06aec3e93af789fa924aa9d2627f3b1..dd1d9a980d8db2bef3acd6ec569119aca051df5f 100644 (file)
@@ -1590,25 +1590,7 @@ void AsmPrinter::EmitInt32(int Value) const {
 /// .set if it avoids relocations.
 void AsmPrinter::EmitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo,
                                      unsigned Size) const {
-  if (!MAI->doesDwarfUseRelocationsAcrossSections())
-    if (OutStreamer->emitAbsoluteSymbolDiff(Hi, Lo, Size))
-      return;
-
-  // Get the Hi-Lo expression.
-  const MCExpr *Diff =
-    MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi, OutContext),
-                            MCSymbolRefExpr::create(Lo, OutContext),
-                            OutContext);
-
-  if (!MAI->doesSetDirectiveSuppressesReloc()) {
-    OutStreamer->EmitValue(Diff, Size);
-    return;
-  }
-
-  // Otherwise, emit with .set (aka assignment).
-  MCSymbol *SetLabel = createTempSymbol("set");
-  OutStreamer->EmitAssignment(SetLabel, Diff);
-  OutStreamer->EmitSymbolValue(SetLabel, Size);
+  OutStreamer->emitAbsoluteSymbolDiff(Hi, Lo, Size);
 }
 
 /// EmitLabelPlusOffset - Emit something like ".long Label+Offset"
index 6de02bcb02d858417f90a6d88ad5f502a9dc602d..a73c171bd1c08ce9b300cd9651f68c07bfb9a855 100644 (file)
@@ -54,21 +54,18 @@ void MCObjectStreamer::flushPendingLabels(MCFragment *F, uint64_t FOffset) {
   }
 }
 
-bool MCObjectStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi,
+void MCObjectStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi,
                                               const MCSymbol *Lo,
                                               unsigned Size) {
-  // Must both be assigned to the same (valid) fragment.
-  if (!Hi->getFragment() || Hi->getFragment() != Lo->getFragment())
-    return false;
-
-  // Must be a data fragment.
-  if (!isa<MCDataFragment>(Hi->getFragment()))
-    return false;
+  // If not assigned to the same (valid) fragment, fallback.
+  if (!Hi->getFragment() || Hi->getFragment() != Lo->getFragment()) {
+    MCStreamer::emitAbsoluteSymbolDiff(Hi, Lo, Size);
+    return;
+  }
 
   assert(Hi->getOffset() >= Lo->getOffset() &&
          "Expected Hi to be greater than Lo");
   EmitIntValue(Hi->getOffset() - Lo->getOffset(), Size);
-  return true;
 }
 
 void MCObjectStreamer::reset() {
index 011969a3da01662da2e4f359a186bd49623a33bc..349de97a17c3c9cbf58de547da1d6a6f932db0d7 100644 (file)
@@ -638,6 +638,25 @@ void MCStreamer::EmitInstruction(const MCInst &Inst,
       visitUsedExpr(*Inst.getOperand(i).getExpr());
 }
 
+void MCStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo,
+                                        unsigned Size) {
+  // Get the Hi-Lo expression.
+  const MCExpr *Diff =
+      MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi, Context),
+                              MCSymbolRefExpr::create(Lo, Context), Context);
+
+  const MCAsmInfo *MAI = Context.getAsmInfo();
+  if (!MAI->doesSetDirectiveSuppressesReloc()) {
+    EmitValue(Diff, Size);
+    return;
+  }
+
+  // Otherwise, emit with .set (aka assignment).
+  MCSymbol *SetLabel = Context.createTempSymbol("set", true);
+  EmitAssignment(SetLabel, Diff);
+  EmitSymbolValue(SetLabel, Size);
+}
+
 void MCStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {}
 void MCStreamer::EmitThumbFunc(MCSymbol *Func) {}
 void MCStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {}