diff --git a/llvm/include/llvm/MC/MCStreamer.h b/llvm/include/llvm/MC/MCStreamer.h index d89ee9ae1260..d4c759d248ce 100644 --- a/llvm/include/llvm/MC/MCStreamer.h +++ b/llvm/include/llvm/MC/MCStreamer.h @@ -249,6 +249,12 @@ namespace llvm { virtual void EmitIntValue(uint64_t Value, unsigned Size, unsigned AddrSpace = 0); + /// EmitAbsValue - Emit the Value, but try to avoid relocations. On MachO + /// this is done by producing + /// foo = value + /// .long foo + void EmitAbsValue(const MCExpr *Value, unsigned Size, + unsigned AddrSpace = 0); virtual void EmitULEB128Value(const MCExpr *Value, unsigned AddrSpace = 0) = 0; diff --git a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp index f737e90b1551..1f7ac95f7b30 100644 --- a/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/AsmPrinterDwarf.cpp @@ -156,7 +156,7 @@ void AsmPrinter::EmitReference(const MCSymbol *Sym, unsigned Encoding) const { const MCExpr *Exp = TLOF.getExprForDwarfReference(Sym, Mang, MMI, Encoding, OutStreamer); - OutStreamer.EmitValue(Exp, GetSizeOfEncodedValue(Encoding), /*addrspace*/0); + OutStreamer.EmitAbsValue(Exp, GetSizeOfEncodedValue(Encoding)); } void AsmPrinter::EmitReference(const GlobalValue *GV, unsigned Encoding)const{ diff --git a/llvm/lib/MC/MCAsmInfoDarwin.cpp b/llvm/lib/MC/MCAsmInfoDarwin.cpp index 1147f02a5964..a382741b5a2b 100644 --- a/llvm/lib/MC/MCAsmInfoDarwin.cpp +++ b/llvm/lib/MC/MCAsmInfoDarwin.cpp @@ -40,7 +40,8 @@ MCAsmInfoDarwin::MCAsmInfoDarwin() { // FIXME: Darwin 10 and newer don't need this. LinkerRequiresNonEmptyDwarfLines = true; - + + NeedsSetToChangeDiffSize = true; HiddenVisibilityAttr = MCSA_PrivateExtern; // Doesn't support protected visibility. ProtectedVisibilityAttr = MCSA_Global; diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp index ab807edd9eab..ce85e462b3d1 100644 --- a/llvm/lib/MC/MCAsmStreamer.cpp +++ b/llvm/lib/MC/MCAsmStreamer.cpp @@ -512,32 +512,6 @@ void MCAsmStreamer::EmitIntValue(uint64_t Value, unsigned Size, EmitValue(MCConstantExpr::Create(Value, getContext()), Size, AddrSpace); } -static bool hasSymbolDifference(const MCExpr *Value) { - switch (Value->getKind()) { - case MCExpr::Target: llvm_unreachable("Can't handle target exprs yet!"); - case MCExpr::Constant: - case MCExpr::SymbolRef: - return false; - case MCExpr::Unary: - return hasSymbolDifference(cast(Value)->getSubExpr()); - case MCExpr::Binary: { - const MCBinaryExpr *BE = cast(Value); - if (BE->getOpcode() == MCBinaryExpr::Sub && - BE->getLHS()->getKind() == MCExpr::SymbolRef && - BE->getRHS()->getKind() == MCExpr::SymbolRef) - return true; - return hasSymbolDifference(BE->getLHS()) || - hasSymbolDifference(BE->getRHS()); - } - } - llvm_unreachable("Switch covers all cases"); -} - -bool MCAsmStreamer::needsSet(const MCExpr *Value) { - return getContext().getAsmInfo().needsSetToChangeDiffSize() && - hasSymbolDifference(Value); -} - void MCAsmStreamer::EmitValue(const MCExpr *Value, unsigned Size, unsigned AddrSpace) { assert(CurSection && "Cannot emit contents before setting section!"); @@ -565,14 +539,6 @@ void MCAsmStreamer::EmitValue(const MCExpr *Value, unsigned Size, } assert(Directive && "Invalid size for machine code value!"); - if (needsSet(Value)) { - MCSymbol *SetLabel = getContext().CreateTempSymbol(); - EmitAssignment(SetLabel, Value); - OS << Directive << *SetLabel; - EmitEOL(); - return; - } - OS << Directive << *Value; EmitEOL(); } diff --git a/llvm/lib/MC/MCDwarf.cpp b/llvm/lib/MC/MCDwarf.cpp index 53731dca7eb1..3e10f9502dbe 100644 --- a/llvm/lib/MC/MCDwarf.cpp +++ b/llvm/lib/MC/MCDwarf.cpp @@ -213,15 +213,8 @@ void MCDwarfFileTable::Emit(MCStreamer *MCOS, // The first 4 bytes is the total length of the information for this // compilation unit (not including these 4 bytes for the length). - // FIXME: We create the dummy TotalLength variable because LineEndSym points - // to the end of the section and the darwin assembler doesn't consider that - // difference an assembly time constant. It might be better for this to be - // proected by a flag. - MCSymbol *TotalLength = MCOS->getContext().CreateTempSymbol(); - MCOS->EmitAssignment(TotalLength, - MakeStartMinusEndExpr(MCOS, LineStartSym, LineEndSym, - 4)); - MCOS->EmitSymbolValue(TotalLength, 4, 0); + MCOS->EmitAbsValue(MakeStartMinusEndExpr(MCOS, LineStartSym, LineEndSym,4), + 4); // Next 2 bytes is the Version, which is Dwarf 2. MCOS->EmitIntValue(2, 2); @@ -233,7 +226,7 @@ void MCDwarfFileTable::Emit(MCStreamer *MCOS, // section to the end of the prologue. Not including the 4 bytes for the // total length, the 2 bytes for the version, and these 4 bytes for the // length of the prologue. - MCOS->EmitValue(MakeStartMinusEndExpr(MCOS, LineStartSym, ProEndSym, + MCOS->EmitAbsValue(MakeStartMinusEndExpr(MCOS, LineStartSym, ProEndSym, (4 + 2 + 4)), 4, 0); diff --git a/llvm/lib/MC/MCStreamer.cpp b/llvm/lib/MC/MCStreamer.cpp index 6df4ae44e40e..096cea7bc7f1 100644 --- a/llvm/lib/MC/MCStreamer.cpp +++ b/llvm/lib/MC/MCStreamer.cpp @@ -7,6 +7,7 @@ // //===----------------------------------------------------------------------===// +#include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCStreamer.h" #include "llvm/MC/MCExpr.h" @@ -72,6 +73,17 @@ void MCStreamer::EmitSLEB128IntValue(int64_t Value, unsigned AddrSpace) { EmitBytes(OSE.str(), AddrSpace); } +void MCStreamer::EmitAbsValue(const MCExpr *Value, unsigned Size, + unsigned AddrSpace) { + if (!getContext().getAsmInfo().needsSetToChangeDiffSize()) { + EmitValue(Value, Size, AddrSpace); + return; + } + MCSymbol *ABS = getContext().CreateTempSymbol(); + EmitAssignment(ABS, Value); + EmitSymbolValue(ABS, Size, AddrSpace); +} + void MCStreamer::EmitSymbolValue(const MCSymbol *Sym, unsigned Size, unsigned AddrSpace) { EmitValue(MCSymbolRefExpr::Create(Sym, getContext()), Size, AddrSpace); diff --git a/llvm/lib/Target/PowerPC/PPCMCAsmInfo.cpp b/llvm/lib/Target/PowerPC/PPCMCAsmInfo.cpp index 89c8cb664c71..3b766b036c46 100644 --- a/llvm/lib/Target/PowerPC/PPCMCAsmInfo.cpp +++ b/llvm/lib/Target/PowerPC/PPCMCAsmInfo.cpp @@ -22,9 +22,6 @@ PPCMCAsmInfoDarwin::PPCMCAsmInfoDarwin(bool is64Bit) { if (!is64Bit) Data64bitsDirective = 0; // We can't emit a 64-bit unit in PPC32 mode. - if (is64Bit) - NeedsSetToChangeDiffSize = true; - AssemblerDialect = 1; // New-Style mnemonics. SupportsDebugInformation= true; // Debug information. } diff --git a/llvm/lib/Target/X86/X86MCAsmInfo.cpp b/llvm/lib/Target/X86/X86MCAsmInfo.cpp index 1ac2d7e6c6d4..f45fdf5a3fb3 100644 --- a/llvm/lib/Target/X86/X86MCAsmInfo.cpp +++ b/llvm/lib/Target/X86/X86MCAsmInfo.cpp @@ -56,10 +56,6 @@ X86MCAsmInfoDarwin::X86MCAsmInfoDarwin(const Triple &Triple) { if (!is64Bit) Data64bitsDirective = 0; // we can't emit a 64-bit unit - // FIXME: Darwin 10 doesn't need this. - if (is64Bit) - NeedsSetToChangeDiffSize = true; - // Use ## as a comment string so that .s files generated by llvm can go // through the GCC preprocessor without causing an error. This is needed // because "clang foo.s" runs the C preprocessor, which is usually reserved diff --git a/llvm/test/MC/MachO/empty-dwarf-lines.s b/llvm/test/MC/MachO/empty-dwarf-lines.s index 8d06d7363da3..4bdc16b55f5c 100644 --- a/llvm/test/MC/MachO/empty-dwarf-lines.s +++ b/llvm/test/MC/MachO/empty-dwarf-lines.s @@ -16,8 +16,8 @@ _c: // CHECK-NEXT: ('size', 44) // CHECK-NEXT: ('offset', 452) // CHECK-NEXT: ('alignment', 0) -// CHECK-NEXT: ('reloc_offset', 496) -// CHECK-NEXT: ('num_reloc', 2) +// CHECK-NEXT: ('reloc_offset', 0) +// CHECK-NEXT: ('num_reloc', 0) // CHECK-NEXT: ('flags', 0x2000000) // CHECK-NEXT: ('reserved1', 0) // CHECK-NEXT: ('reserved2', 0)