summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorTim Northover <tnorthover@apple.com>2014-03-29 07:34:53 +0000
committerTim Northover <tnorthover@apple.com>2014-03-29 07:34:53 +0000
commit53d32518512bb30d0c43376bdd334ddfa0dbcd64 (patch)
treeb5df1bf6cf477afa53cf56c89c5fe8d51dbf5eff /llvm/lib
parent5627670e8429c811032971211cfe3da89f0221b4 (diff)
downloadbcm5719-llvm-53d32518512bb30d0c43376bdd334ddfa0dbcd64.tar.gz
bcm5719-llvm-53d32518512bb30d0c43376bdd334ddfa0dbcd64.zip
MachO: Add linker-optimisation hint framework to MC.
Another part of the ARM64 backend (so tests will be following soon). This is currently used by the linker to relax adrp/ldr pairs into nops where possible, though could well be more broadly applicable. llvm-svn: 205084
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/MC/CMakeLists.txt1
-rw-r--r--llvm/lib/MC/MCAsmStreamer.cpp22
-rw-r--r--llvm/lib/MC/MCAssembler.cpp1
-rw-r--r--llvm/lib/MC/MCLinkerOptimizationHint.cpp30
-rw-r--r--llvm/lib/MC/MCMachOStreamer.cpp5
-rw-r--r--llvm/lib/MC/MachObjectWriter.cpp29
6 files changed, 86 insertions, 2 deletions
diff --git a/llvm/lib/MC/CMakeLists.txt b/llvm/lib/MC/CMakeLists.txt
index eb3f9e52d73..ab7dabc9c74 100644
--- a/llvm/lib/MC/CMakeLists.txt
+++ b/llvm/lib/MC/CMakeLists.txt
@@ -24,6 +24,7 @@ add_llvm_library(LLVMMC
MCInstPrinter.cpp
MCInstrAnalysis.cpp
MCLabel.cpp
+ MCLinkerOptimizationHint.cpp
MCMachOStreamer.cpp
MCMachObjectTargetWriter.cpp
MCModule.cpp
diff --git a/llvm/lib/MC/MCAsmStreamer.cpp b/llvm/lib/MC/MCAsmStreamer.cpp
index 59af4101afa..cc30d056a21 100644
--- a/llvm/lib/MC/MCAsmStreamer.cpp
+++ b/llvm/lib/MC/MCAsmStreamer.cpp
@@ -126,6 +126,7 @@ public:
void ChangeSection(const MCSection *Section,
const MCExpr *Subsection) override;
+ void EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) override;
void EmitLabel(MCSymbol *Symbol) override;
void EmitDebugLabel(MCSymbol *Symbol) override;
@@ -342,6 +343,27 @@ void MCAsmStreamer::EmitLabel(MCSymbol *Symbol) {
EmitEOL();
}
+void MCAsmStreamer::EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) {
+ StringRef str = MCLOHIdToName(Kind);
+
+#ifndef NDEBUG
+ int NbArgs = MCLOHIdToNbArgs(Kind);
+ assert(NbArgs != -1 && ((size_t)NbArgs) == Args.size() && "Malformed LOH!");
+ assert(str != "" && "Invalid LOH name");
+#endif
+
+ OS << "\t" << MCLOHDirectiveName() << " " << str << "\t";
+ bool IsFirst = true;
+ for (MCLOHArgs::const_iterator It = Args.begin(), EndIt = Args.end();
+ It != EndIt; ++It) {
+ if (!IsFirst)
+ OS << ", ";
+ IsFirst = false;
+ OS << **It;
+ }
+ EmitEOL();
+}
+
void MCAsmStreamer::EmitDebugLabel(MCSymbol *Symbol) {
assert(Symbol->isUndefined() && "Cannot define a symbol twice!");
MCStreamer::EmitDebugLabel(Symbol);
diff --git a/llvm/lib/MC/MCAssembler.cpp b/llvm/lib/MC/MCAssembler.cpp
index 5536087bd0c..724ca292bef 100644
--- a/llvm/lib/MC/MCAssembler.cpp
+++ b/llvm/lib/MC/MCAssembler.cpp
@@ -355,6 +355,7 @@ void MCAssembler::reset() {
getBackend().reset();
getEmitter().reset();
getWriter().reset();
+ getLOHContainer().reset();
}
bool MCAssembler::isSymbolLinkerVisible(const MCSymbol &Symbol) const {
diff --git a/llvm/lib/MC/MCLinkerOptimizationHint.cpp b/llvm/lib/MC/MCLinkerOptimizationHint.cpp
new file mode 100644
index 00000000000..628a6156fd8
--- /dev/null
+++ b/llvm/lib/MC/MCLinkerOptimizationHint.cpp
@@ -0,0 +1,30 @@
+//===-- llvm/MC/MCLinkerOptimizationHint.cpp ----- LOH handling -*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/MC/MCLinkerOptimizationHint.h"
+#include "llvm/MC/MCAsmLayout.h"
+#include "llvm/Support/LEB128.h"
+#include "llvm/MC/MCStreamer.h"
+
+using namespace llvm;
+
+namespace llvm {
+template<>
+void MCLOHDirective::Emit_impl(raw_ostream &OutStream,
+ const MachObjectWriter &ObjWriter,
+ const MCAsmLayout &Layout) const {
+ const MCAssembler &Asm = Layout.getAssembler();
+ encodeULEB128(Kind, OutStream);
+ encodeULEB128(Args.size(), OutStream);
+ for (LOHArgs::const_iterator It = Args.begin(), EndIt = Args.end();
+ It != EndIt; ++It)
+ encodeULEB128(ObjWriter.getSymbolAddress(&Asm.getSymbolData(**It), Layout),
+ OutStream);
+}
+} // end namespace llvm
diff --git a/llvm/lib/MC/MCMachOStreamer.cpp b/llvm/lib/MC/MCMachOStreamer.cpp
index 742f7846496..7e437f4bcb8 100644
--- a/llvm/lib/MC/MCMachOStreamer.cpp
+++ b/llvm/lib/MC/MCMachOStreamer.cpp
@@ -17,6 +17,7 @@
#include "llvm/MC/MCDwarf.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
+#include "llvm/MC/MCLinkerOptimizationHint.h"
#include "llvm/MC/MCMachOSymbolFlags.h"
#include "llvm/MC/MCObjectFileInfo.h"
#include "llvm/MC/MCObjectStreamer.h"
@@ -104,6 +105,10 @@ public:
llvm_unreachable("macho doesn't support this directive");
}
+ void EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) override {
+ getAssembler().getLOHContainer().addDirective(Kind, Args);
+ }
+
void FinishImpl() override;
};
diff --git a/llvm/lib/MC/MachObjectWriter.cpp b/llvm/lib/MC/MachObjectWriter.cpp
index bbe589f3385..5fcea5f06c1 100644
--- a/llvm/lib/MC/MachObjectWriter.cpp
+++ b/llvm/lib/MC/MachObjectWriter.cpp
@@ -761,6 +761,14 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm,
LoadCommandsSize += sizeof(MachO::linkedit_data_command);
}
+ // Add the loh load command size, if used.
+ uint64_t LOHRawSize = Asm.getLOHContainer().getEmitSize(*this, Layout);
+ uint64_t LOHSize = RoundUpToAlignment(LOHRawSize, is64Bit() ? 8 : 4);
+ if (LOHSize) {
+ ++NumLoadCommands;
+ LoadCommandsSize += sizeof(MachO::linkedit_data_command);
+ }
+
// Add the symbol table load command sizes, if used.
unsigned NumSymbols = LocalSymbolData.size() + ExternalSymbolData.size() +
UndefinedSymbolData.size();
@@ -849,6 +857,12 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm,
DataRegionsSize);
}
+ // Write the loh load command, if used.
+ uint64_t LOHTableEnd = DataInCodeTableEnd + LOHSize;
+ if (LOHSize)
+ WriteLinkeditLoadCommand(MachO::LC_LINKER_OPTIMIZATION_HINT,
+ DataInCodeTableEnd, LOHSize);
+
// Write the symbol table load command, if used.
if (NumSymbols) {
unsigned FirstLocalSymbol = 0;
@@ -865,10 +879,10 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm,
// If used, the indirect symbols are written after the section data.
if (NumIndirectSymbols)
- IndirectSymbolOffset = DataInCodeTableEnd;
+ IndirectSymbolOffset = LOHTableEnd;
// The symbol table is written after the indirect symbol data.
- uint64_t SymbolTableOffset = DataInCodeTableEnd + IndirectSymbolSize;
+ uint64_t SymbolTableOffset = LOHTableEnd + IndirectSymbolSize;
// The string table is written after symbol table.
uint64_t StringTableOffset =
@@ -935,6 +949,17 @@ void MachObjectWriter::WriteObject(MCAssembler &Asm,
Write16(Data->Kind);
}
+ // Write out the loh commands, if there is one.
+ if (LOHSize) {
+#ifndef NDEBUG
+ unsigned Start = OS.tell();
+#endif
+ Asm.getLOHContainer().Emit(*this, Layout);
+ // Pad to a multiple of the pointer size.
+ WriteBytes("", OffsetToAlignment(LOHRawSize, is64Bit() ? 8 : 4));
+ assert(OS.tell() - Start == LOHSize);
+ }
+
// Write the symbol table data, if used.
if (NumSymbols) {
// Write the indirect symbol entries.
OpenPOWER on IntegriCloud