diff options
author | Hans Wennborg <hans@hanshq.net> | 2018-01-30 09:31:00 +0000 |
---|---|---|
committer | Hans Wennborg <hans@hanshq.net> | 2018-01-30 09:31:00 +0000 |
commit | 98b79f2cd78d57b8e5f5307ac889fa264cddcc36 (patch) | |
tree | 7636da279d64d7a07d0580e24e617f06ca3ad6fd | |
parent | f1286127b73c0d81ced8595af62e78ed703ced8b (diff) |
Merging r322108, r322123 and r322131:
------------------------------------------------------------------------
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
-rw-r--r-- | include/llvm/MC/MCFragment.h | 15 | ||||
-rw-r--r-- | include/llvm/MC/MCObjectStreamer.h | 1 | ||||
-rw-r--r-- | include/llvm/MC/MCStreamer.h | 2 | ||||
-rw-r--r-- | lib/MC/MCAsmStreamer.cpp | 16 | ||||
-rw-r--r-- | lib/MC/MCAssembler.cpp | 16 | ||||
-rw-r--r-- | lib/MC/MCMachOStreamer.cpp | 28 | ||||
-rw-r--r-- | lib/MC/MCObjectStreamer.cpp | 19 | ||||
-rw-r--r-- | lib/MC/MCStreamer.cpp | 3 | ||||
-rw-r--r-- | lib/MC/MCWinCOFFStreamer.cpp | 19 | ||||
-rw-r--r-- | lib/MC/WasmObjectWriter.cpp | 5 | ||||
-rw-r--r-- | test/MC/X86/eval-fill.s | 17 |
11 files changed, 68 insertions, 73 deletions
diff --git a/include/llvm/MC/MCFragment.h b/include/llvm/MC/MCFragment.h index 7ebde03a758c..85b55e85469a 100644 --- a/include/llvm/MC/MCFragment.h +++ b/include/llvm/MC/MCFragment.h @@ -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; diff --git a/include/llvm/MC/MCObjectStreamer.h b/include/llvm/MC/MCObjectStreamer.h index a3dbc56ebc10..43ed00b4a7a7 100644 --- a/include/llvm/MC/MCObjectStreamer.h +++ b/include/llvm/MC/MCObjectStreamer.h @@ -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, diff --git a/include/llvm/MC/MCStreamer.h b/include/llvm/MC/MCStreamer.h index a82051700708..28b326ae9b87 100644 --- a/include/llvm/MC/MCStreamer.h +++ b/include/llvm/MC/MCStreamer.h @@ -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. /// diff --git a/lib/MC/MCAsmStreamer.cpp b/lib/MC/MCAsmStreamer.cpp index e521b6e7c704..bddd264fe30b 100644 --- a/lib/MC/MCAsmStreamer.cpp +++ b/lib/MC/MCAsmStreamer.cpp @@ -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; diff --git a/lib/MC/MCAssembler.cpp b/lib/MC/MCAssembler.cpp index 01d165944bec..bd881b4d6e85 100644 --- a/lib/MC/MCAssembler.cpp +++ b/lib/MC/MCAssembler.cpp @@ -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) diff --git a/lib/MC/MCMachOStreamer.cpp b/lib/MC/MCMachOStreamer.cpp index 82b75afabb3c..3969143bb2c7 100644 --- a/lib/MC/MCMachOStreamer.cpp +++ b/lib/MC/MCMachOStreamer.cpp @@ -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 diff --git a/lib/MC/MCObjectStreamer.cpp b/lib/MC/MCObjectStreamer.cpp index 15cc0faf5407..aecb3844622b 100644 --- a/lib/MC/MCObjectStreamer.cpp +++ b/lib/MC/MCObjectStreamer.cpp @@ -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, diff --git a/lib/MC/MCStreamer.cpp b/lib/MC/MCStreamer.cpp index 6e801ed8777c..ed10ccbbb742 100644 --- a/lib/MC/MCStreamer.cpp +++ b/lib/MC/MCStreamer.cpp @@ -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) { diff --git a/lib/MC/MCWinCOFFStreamer.cpp b/lib/MC/MCWinCOFFStreamer.cpp index c2583d95c5ed..8582d9adafb8 100644 --- a/lib/MC/MCWinCOFFStreamer.cpp +++ b/lib/MC/MCWinCOFFStreamer.cpp @@ -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, diff --git a/lib/MC/WasmObjectWriter.cpp b/lib/MC/WasmObjectWriter.cpp index 0f0b645492ee..66236e3abfab 100644 --- a/lib/MC/WasmObjectWriter.cpp +++ b/lib/MC/WasmObjectWriter.cpp @@ -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 index 000000000000..f09166ee0f12 --- /dev/null +++ b/test/MC/X86/eval-fill.s @@ -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) |