]> granicus.if.org Git - llvm/commitdiff
Merging r322108, r322123 and r322131:
authorHans Wennborg <hans@hanshq.net>
Tue, 30 Jan 2018 09:31:00 +0000 (09:31 +0000)
committerHans Wennborg <hans@hanshq.net>
Tue, 30 Jan 2018 09:31:00 +0000 (09:31 +0000)
------------------------------------------------------------------------
r322108 | rafael | 2018-01-09 20:29:33 +0100 (Tue, 09 Jan 2018) | 3 lines

Make one of the emitFill methods non virtual. NFC.

This is just preparatory work to fix PR35858.
------------------------------------------------------------------------

------------------------------------------------------------------------
r322123 | rafael | 2018-01-09 22:55:10 +0100 (Tue, 09 Jan 2018) | 3 lines

Don't create MCFillFragment directly.

Instead use higher level APIs that take care of most bookkeeping.
------------------------------------------------------------------------

------------------------------------------------------------------------
r322131 | rafael | 2018-01-09 23:48:37 +0100 (Tue, 09 Jan 2018) | 4 lines

Use a MCExpr for the size of MCFillFragment.

This allows the size to be found during ralaxation. This fixes
pr35858.
------------------------------------------------------------------------

git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_60@323735 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/MC/MCFragment.h
include/llvm/MC/MCObjectStreamer.h
include/llvm/MC/MCStreamer.h
lib/MC/MCAsmStreamer.cpp
lib/MC/MCAssembler.cpp
lib/MC/MCMachOStreamer.cpp
lib/MC/MCObjectStreamer.cpp
lib/MC/MCStreamer.cpp
lib/MC/MCWinCOFFStreamer.cpp
lib/MC/WasmObjectWriter.cpp
test/MC/X86/eval-fill.s [new file with mode: 0644]

index 7ebde03a758c59c5495ac39f4f8f4be4804af3e8..85b55e85469a1d44cf3aa98ef54b90e507ba0412 100644 (file)
@@ -422,14 +422,21 @@ class MCFillFragment : public MCFragment {
   uint8_t Value;
 
   /// The number of bytes to insert.
-  uint64_t Size;
+  const MCExpr &Size;
+
+  /// Source location of the directive that this fragment was created for.
+  SMLoc Loc;
 
 public:
-  MCFillFragment(uint8_t Value, uint64_t Size, MCSection *Sec = nullptr)
-      : MCFragment(FT_Fill, false, 0, Sec), Value(Value), Size(Size) {}
+  MCFillFragment(uint8_t Value, const MCExpr &Size, SMLoc Loc,
+                 MCSection *Sec = nullptr)
+      : MCFragment(FT_Fill, false, 0, Sec), Value(Value), Size(Size), Loc(Loc) {
+  }
 
   uint8_t getValue() const { return Value; }
-  uint64_t getSize() const { return Size; }
+  const MCExpr &getSize() const { return Size; }
+
+  SMLoc getLoc() const { return Loc; }
 
   static bool classof(const MCFragment *F) {
     return F->getKind() == MCFragment::FT_Fill;
index a3dbc56ebc10f5ab22f7dbcbe239cccd3fcd679c..43ed00b4a7a7f917169af6a717f1d21c137b54f4 100644 (file)
@@ -161,7 +161,6 @@ public:
   bool EmitRelocDirective(const MCExpr &Offset, StringRef Name,
                           const MCExpr *Expr, SMLoc Loc) override;
   using MCStreamer::emitFill;
-  void emitFill(uint64_t NumBytes, uint8_t FillValue) override;
   void emitFill(const MCExpr &NumBytes, uint64_t FillValue,
                 SMLoc Loc = SMLoc()) override;
   void emitFill(const MCExpr &NumValues, int64_t Size, int64_t Expr,
index a82051700708258399be00f1429faa62f06bda1d..28b326ae9b87a9e24b40f743f8f26536c73503c8 100644 (file)
@@ -662,7 +662,7 @@ public:
 
   /// \brief Emit NumBytes bytes worth of the value specified by FillValue.
   /// This implements directives such as '.space'.
-  virtual void emitFill(uint64_t NumBytes, uint8_t FillValue);
+  void emitFill(uint64_t NumBytes, uint8_t FillValue);
 
   /// \brief Emit \p Size bytes worth of the value specified by \p FillValue.
   ///
index e521b6e7c704982ee486b620895a7fd1375077ab..bddd264fe30b0e4c7fb0da50280653c79e43086e 100644 (file)
@@ -192,9 +192,6 @@ public:
 
   void EmitGPRel32Value(const MCExpr *Value) override;
 
-
-  void emitFill(uint64_t NumBytes, uint8_t FillValue) override;
-
   void emitFill(const MCExpr &NumBytes, uint64_t FillValue,
                 SMLoc Loc = SMLoc()) override;
 
@@ -965,17 +962,12 @@ void MCAsmStreamer::EmitGPRel32Value(const MCExpr *Value) {
   EmitEOL();
 }
 
-/// emitFill - Emit NumBytes bytes worth of the value specified by
-/// FillValue.  This implements directives such as '.space'.
-void MCAsmStreamer::emitFill(uint64_t NumBytes, uint8_t FillValue) {
-  if (NumBytes == 0) return;
-
-  const MCExpr *E = MCConstantExpr::create(NumBytes, getContext());
-  emitFill(*E, FillValue);
-}
-
 void MCAsmStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,
                              SMLoc Loc) {
+  int64_t IntNumBytes;
+  if (NumBytes.evaluateAsAbsolute(IntNumBytes) && IntNumBytes == 0)
+    return;
+
   if (const char *ZeroDirective = MAI->getZeroDirective()) {
     // FIXME: Emit location directives
     OS << ZeroDirective;
index 01d165944becedbe5a9efc741d516b32a8fa77b7..bd881b4d6e851771c26d42d6d757eca21865e8e7 100644 (file)
@@ -281,8 +281,18 @@ uint64_t MCAssembler::computeFragmentSize(const MCAsmLayout &Layout,
     return cast<MCRelaxableFragment>(F).getContents().size();
   case MCFragment::FT_CompactEncodedInst:
     return cast<MCCompactEncodedInstFragment>(F).getContents().size();
-  case MCFragment::FT_Fill:
-    return cast<MCFillFragment>(F).getSize();
+  case MCFragment::FT_Fill: {
+    auto &FF = cast<MCFillFragment>(F);
+    int64_t Size = 0;
+    if (!FF.getSize().evaluateAsAbsolute(Size, Layout))
+      getContext().reportError(FF.getLoc(),
+                               "expected assembly-time absolute expression");
+    if (Size < 0) {
+      getContext().reportError(FF.getLoc(), "invalid number of bytes");
+      return 0;
+    }
+    return Size;
+  }
 
   case MCFragment::FT_LEB:
     return cast<MCLEBFragment>(F).getContents().size();
@@ -540,7 +550,7 @@ static void writeFragment(const MCAssembler &Asm, const MCAsmLayout &Layout,
     for (unsigned I = 1; I < MaxChunkSize; ++I)
       Data[I] = Data[0];
 
-    uint64_t Size = FF.getSize();
+    uint64_t Size = FragmentSize;
     for (unsigned ChunkSize = MaxChunkSize; ChunkSize; ChunkSize /= 2) {
       StringRef Ref(Data, ChunkSize);
       for (uint64_t I = 0, E = Size / ChunkSize; I != E; ++I)
index 82b75afabb3cdcfdb4ee66542becd60bc0550768..3969143bb2c72a0532b64331e6f44741d189dc5f 100644 (file)
@@ -411,29 +411,19 @@ void MCMachOStreamer::EmitLocalCommonSymbol(MCSymbol *Symbol, uint64_t Size,
 
 void MCMachOStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol,
                                    uint64_t Size, unsigned ByteAlignment) {
-  getAssembler().registerSection(*Section);
-
-  // The symbol may not be present, which only creates the section.
-  if (!Symbol)
-    return;
-
   // On darwin all virtual sections have zerofill type.
   assert(Section->isVirtualSection() && "Section does not have zerofill type!");
 
-  assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
+  PushSection();
+  SwitchSection(Section);
 
-  getAssembler().registerSymbol(*Symbol);
-
-  // Emit an align fragment if necessary.
-  if (ByteAlignment != 1)
-    new MCAlignFragment(ByteAlignment, 0, 0, ByteAlignment, Section);
-
-  MCFragment *F = new MCFillFragment(0, Size, Section);
-  Symbol->setFragment(F);
-
-  // Update the maximum alignment on the zero fill section if necessary.
-  if (ByteAlignment > Section->getAlignment())
-    Section->setAlignment(ByteAlignment);
+  // The symbol may not be present, which only creates the section.
+  if (Symbol) {
+    EmitValueToAlignment(ByteAlignment, 0, 1, 0);
+    EmitLabel(Symbol);
+    EmitZeros(Size);
+  }
+  PopSection();
 }
 
 // This should always be called with the thread local bss section.  Like the
index 15cc0faf5407ff77cc8ca5b78ddd9015e772d29e..aecb3844622b1c1f059d735ec62c160b2b992fca 100644 (file)
@@ -577,28 +577,13 @@ bool MCObjectStreamer::EmitRelocDirective(const MCExpr &Offset, StringRef Name,
   return false;
 }
 
-void MCObjectStreamer::emitFill(uint64_t NumBytes, uint8_t FillValue) {
-  assert(getCurrentSectionOnly() && "need a section");
-  insert(new MCFillFragment(FillValue, NumBytes));
-}
-
 void MCObjectStreamer::emitFill(const MCExpr &NumBytes, uint64_t FillValue,
                                 SMLoc Loc) {
   MCDataFragment *DF = getOrCreateDataFragment();
   flushPendingLabels(DF, DF->getContents().size());
 
-  int64_t IntNumBytes;
-  if (!NumBytes.evaluateAsAbsolute(IntNumBytes, getAssembler())) {
-    getContext().reportError(Loc, "expected absolute expression");
-    return;
-  }
-
-  if (IntNumBytes <= 0) {
-    getContext().reportError(Loc, "invalid number of bytes");
-    return;
-  }
-
-  emitFill(IntNumBytes, FillValue);
+  assert(getCurrentSectionOnly() && "need a section");
+  insert(new MCFillFragment(FillValue, NumBytes, Loc));
 }
 
 void MCObjectStreamer::emitFill(const MCExpr &NumValues, int64_t Size,
index 6e801ed8777cf211591c7ae81e04ead01023a18d..ed10ccbbb742a825380980e7012060d88b97d14c 100644 (file)
@@ -184,8 +184,7 @@ void MCStreamer::EmitGPRel32Value(const MCExpr *Value) {
 /// Emit NumBytes bytes worth of the value specified by FillValue.
 /// This implements directives such as '.space'.
 void MCStreamer::emitFill(uint64_t NumBytes, uint8_t FillValue) {
-  for (uint64_t i = 0, e = NumBytes; i != e; ++i)
-    EmitIntValue(FillValue, 1);
+  emitFill(*MCConstantExpr::create(NumBytes, getContext()), FillValue);
 }
 
 void MCStreamer::emitFill(uint64_t NumValues, int64_t Size, int64_t Expr) {
index c2583d95c5eda1a479251a0f9c471533402ce25f..8582d9adafb8453ad161ed0558b4cd94182e0926 100644 (file)
@@ -257,20 +257,13 @@ void MCWinCOFFStreamer::EmitLocalCommonSymbol(MCSymbol *S, uint64_t Size,
   auto *Symbol = cast<MCSymbolCOFF>(S);
 
   MCSection *Section = getContext().getObjectFileInfo()->getBSSSection();
-  getAssembler().registerSection(*Section);
-  if (Section->getAlignment() < ByteAlignment)
-    Section->setAlignment(ByteAlignment);
-
-  getAssembler().registerSymbol(*Symbol);
+  PushSection();
+  SwitchSection(Section);
+  EmitValueToAlignment(ByteAlignment, 0, 1, 0);
+  EmitLabel(Symbol);
   Symbol->setExternal(false);
-
-  if (ByteAlignment != 1)
-    new MCAlignFragment(ByteAlignment, /*Value=*/0, /*ValueSize=*/0,
-                        ByteAlignment, Section);
-
-  MCFillFragment *Fragment = new MCFillFragment(
-      /*Value=*/0, Size, Section);
-  Symbol->setFragment(Fragment);
+  EmitZeros(Size);
+  PopSection();
 }
 
 void MCWinCOFFStreamer::EmitZerofill(MCSection *Section, MCSymbol *Symbol,
index 0f0b645492ee00971feb2d24a08605315c214d5a..66236e3abfaba3278796cb690cb04ba1e7a12710 100644 (file)
@@ -528,7 +528,10 @@ static void addData(SmallVectorImpl<char> &DataBytes,
                                              Align->getMaxBytesToEmit());
       DataBytes.resize(Size, Value);
     } else if (auto *Fill = dyn_cast<MCFillFragment>(&Frag)) {
-      DataBytes.insert(DataBytes.end(), Fill->getSize(), Fill->getValue());
+      int64_t Size;
+      if (!Fill->getSize().evaluateAsAbsolute(Size))
+        llvm_unreachable("The fill should be an assembler constant");
+      DataBytes.insert(DataBytes.end(), Size, Fill->getValue());
     } else {
       const auto &DataFrag = cast<MCDataFragment>(Frag);
       const SmallVectorImpl<char> &Contents = DataFrag.getContents();
diff --git a/test/MC/X86/eval-fill.s b/test/MC/X86/eval-fill.s
new file mode 100644 (file)
index 0000000..f09166e
--- /dev/null
@@ -0,0 +1,17 @@
+// RUN: llvm-mc -filetype=obj %s -o - -triple x86_64-pc-linux | llvm-readobj -s | FileCheck %s
+
+// CHECK:      Name: .text
+// CHECK-NEXT: Type: SHT_PROGBITS
+// CHECK-NEXT: Flags [
+// CHECK-NEXT:   SHF_ALLOC
+// CHECK-NEXT:   SHF_EXECINSTR
+// CHECK-NEXT: ]
+// CHECK-NEXT: Address:
+// CHECK-NEXT: Offset:
+// CHECK-NEXT: Size: 4092
+
+        .globl  foo
+foo:
+        .space 4
+bar:
+        .space  4092 - (bar - foo)