diff options
Diffstat (limited to 'llvm/lib/MC')
-rw-r--r-- | llvm/lib/MC/MCAsmStreamer.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/MC/MCObjectStreamer.cpp | 27 | ||||
-rw-r--r-- | llvm/lib/MC/MCStreamer.cpp | 22 |
3 files changed, 38 insertions, 15 deletions
diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp index 4e8dcf61491..927c1889c88 100644 --- a/llvm/lib/MC/MCAsmStreamer.cpp +++ b/llvm/lib/MC/MCAsmStreamer.cpp @@ -910,7 +910,7 @@ void MCAsmStreamer::EmitULEB128Value(const MCExpr *Value) { EmitULEB128IntValue(IntValue); return; } - OS << ".uleb128 "; + OS << "\t.uleb128 "; Value->print(OS, MAI); EmitEOL(); } @@ -921,7 +921,7 @@ void MCAsmStreamer::EmitSLEB128Value(const MCExpr *Value) { EmitSLEB128IntValue(IntValue); return; } - OS << ".sleb128 "; + OS << "\t.sleb128 "; Value->print(OS, MAI); EmitEOL(); } diff --git a/llvm/lib/MC/MCObjectStreamer.cpp b/llvm/lib/MC/MCObjectStreamer.cpp index 230c02188a6..9c69a5a962d 100644 --- a/llvm/lib/MC/MCObjectStreamer.cpp +++ b/llvm/lib/MC/MCObjectStreamer.cpp @@ -51,17 +51,34 @@ void MCObjectStreamer::flushPendingLabels(MCFragment *F, uint64_t FOffset) { PendingLabels.clear(); } +// As a compile-time optimization, avoid allocating and evaluating an MCExpr +// tree for (Hi - Lo) when Hi and Lo are offsets into the same fragment. +static Optional<uint64_t> absoluteSymbolDiff(const MCSymbol *Hi, + const MCSymbol *Lo) { + if (!Hi->getFragment() || Hi->getFragment() != Lo->getFragment() || + Hi->isVariable() || Lo->isVariable()) + return None; + + return Hi->getOffset() - Lo->getOffset(); +} + void MCObjectStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo, unsigned Size) { - // If not assigned to the same (valid) fragment, fallback. - if (!Hi->getFragment() || Hi->getFragment() != Lo->getFragment() || - Hi->isVariable() || Lo->isVariable()) { - MCStreamer::emitAbsoluteSymbolDiff(Hi, Lo, Size); + if (Optional<uint64_t> Diff = absoluteSymbolDiff(Hi, Lo)) { + EmitIntValue(*Diff, Size); return; } + MCStreamer::emitAbsoluteSymbolDiff(Hi, Lo, Size); +} - EmitIntValue(Hi->getOffset() - Lo->getOffset(), Size); +void MCObjectStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi, + const MCSymbol *Lo) { + if (Optional<uint64_t> Diff = absoluteSymbolDiff(Hi, Lo)) { + EmitULEB128IntValue(*Diff); + return; + } + MCStreamer::emitAbsoluteSymbolDiffAsULEB128(Hi, Lo); } void MCObjectStreamer::reset() { diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp index 9dcd1e9101c..bc9c93f144e 100644 --- a/llvm/lib/MC/MCStreamer.cpp +++ b/llvm/lib/MC/MCStreamer.cpp @@ -120,20 +120,16 @@ void MCStreamer::EmitIntValue(uint64_t Value, unsigned Size) { EmitBytes(StringRef(buf, Size)); } -/// EmitULEB128Value - Special case of EmitULEB128Value that avoids the +/// EmitULEB128IntValue - Special case of EmitULEB128Value that avoids the /// client having to pass in a MCExpr for constant integers. -void MCStreamer::EmitPaddedULEB128IntValue(uint64_t Value, unsigned PadTo) { +void MCStreamer::EmitULEB128IntValue(uint64_t Value) { SmallString<128> Tmp; raw_svector_ostream OSE(Tmp); - encodeULEB128(Value, OSE, PadTo); + encodeULEB128(Value, OSE); EmitBytes(OSE.str()); } -void MCStreamer::EmitULEB128IntValue(uint64_t Value) { - EmitPaddedULEB128IntValue(Value, 0); -} - -/// EmitSLEB128Value - Special case of EmitSLEB128Value that avoids the +/// EmitSLEB128IntValue - Special case of EmitSLEB128Value that avoids the /// client having to pass in a MCExpr for constant integers. void MCStreamer::EmitSLEB128IntValue(int64_t Value) { SmallString<128> Tmp; @@ -902,6 +898,16 @@ void MCStreamer::emitAbsoluteSymbolDiff(const MCSymbol *Hi, const MCSymbol *Lo, EmitSymbolValue(SetLabel, Size); } +void MCStreamer::emitAbsoluteSymbolDiffAsULEB128(const MCSymbol *Hi, + const MCSymbol *Lo) { + // Get the Hi-Lo expression. + const MCExpr *Diff = + MCBinaryExpr::createSub(MCSymbolRefExpr::create(Hi, Context), + MCSymbolRefExpr::create(Lo, Context), Context); + + EmitULEB128Value(Diff); +} + void MCStreamer::EmitAssemblerFlag(MCAssemblerFlag Flag) {} void MCStreamer::EmitThumbFunc(MCSymbol *Func) {} void MCStreamer::EmitSymbolDesc(MCSymbol *Symbol, unsigned DescValue) {} |