<div dir="rtl"><div dir="ltr">Hi Tim</div><div dir="ltr"><br></div><div dir="ltr">Visual C++ 2013 does not generate any code when </div><div dir="ltr"><br></div><div dir="ltr"><div dir="ltr">  template<></div><div dir="ltr">

  void MCLOHDirective::Emit_impl(raw_ostream &OutStream,</div><div><br></div><div>and so fails linking on missing MCLOHDirective::Emit_impl.</div><div><br></div><div>It does accept</div><div><br></div><div><div dir="ltr">

  void MCLOHDirective::Emit_impl(raw_ostream &OutStream,</div></div><div><br></div><div>(without template<>) and link OK.</div><div><br></div><div>I'm not sure enough to commit this change, though.</div><div>

<br></div><div>Yaron</div><div><br></div><div><br></div></div></div><div class="gmail_extra"><br><br><div class="gmail_quote"><div dir="ltr">2014-03-29 10:35 GMT+03:00 Tim Northover <span dir="ltr"><<a href="mailto:tnorthover@apple.com" target="_blank">tnorthover@apple.com</a>></span>:</div>

<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: tnorthover<br>
Date: Sat Mar 29 02:34:53 2014<br>
New Revision: 205084<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=205084&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=205084&view=rev</a><br>
Log:<br>
MachO: Add linker-optimisation hint framework to MC.<br>
<br>
Another part of the ARM64 backend (so tests will be following soon).<br>
This is currently used by the linker to relax adrp/ldr pairs into nops<br>
where possible, though could well be more broadly applicable.<br>
<br>
Added:<br>
    llvm/trunk/include/llvm/MC/MCLinkerOptimizationHint.h<br>
    llvm/trunk/lib/MC/MCLinkerOptimizationHint.cpp<br>
Modified:<br>
    llvm/trunk/include/llvm/MC/MCAssembler.h<br>
    llvm/trunk/include/llvm/MC/MCStreamer.h<br>
    llvm/trunk/include/llvm/Support/MachO.h<br>
    llvm/trunk/lib/MC/CMakeLists.txt<br>
    llvm/trunk/lib/MC/MCAsmStreamer.cpp<br>
    llvm/trunk/lib/MC/MCAssembler.cpp<br>
    llvm/trunk/lib/MC/MCMachOStreamer.cpp<br>
    llvm/trunk/lib/MC/MachObjectWriter.cpp<br>
<br>
Modified: llvm/trunk/include/llvm/MC/MCAssembler.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCAssembler.h?rev=205084&r1=205083&r2=205084&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCAssembler.h?rev=205084&r1=205083&r2=205084&view=diff</a><br>


==============================================================================<br>
--- llvm/trunk/include/llvm/MC/MCAssembler.h (original)<br>
+++ llvm/trunk/include/llvm/MC/MCAssembler.h Sat Mar 29 02:34:53 2014<br>
@@ -18,6 +18,7 @@<br>
 #include "llvm/MC/MCDirectives.h"<br>
 #include "llvm/MC/MCFixup.h"<br>
 #include "llvm/MC/MCInst.h"<br>
+#include "llvm/MC/MCLinkerOptimizationHint.h"<br>
 #include "llvm/MC/MCSubtargetInfo.h"<br>
 #include "llvm/Support/Casting.h"<br>
 #include "llvm/Support/DataTypes.h"<br>
@@ -932,6 +933,10 @@ private:<br>
   // which flags to be set.<br>
   unsigned ELFHeaderEFlags;<br>
<br>
+  /// Used to communicate Linker Optimization Hint information between<br>
+  /// the Streamer and the .o writer<br>
+  MCLOHContainer LOHContainer;<br>
+<br>
   VersionMinInfoType VersionMinInfo;<br>
 private:<br>
   /// Evaluate a fixup to a relocatable expression and the value which should be<br>
@@ -1175,6 +1180,19 @@ public:<br>
   size_t data_region_size() const { return DataRegions.size(); }<br>
<br>
   /// @}<br>
+  /// @name Data Region List Access<br>
+  /// @{<br>
+<br>
+  // FIXME: This is a total hack, this should not be here. Once things are<br>
+  // factored so that the streamer has direct access to the .o writer, it can<br>
+  // disappear.<br>
+  MCLOHContainer & getLOHContainer() {<br>
+    return LOHContainer;<br>
+  }<br>
+  const MCLOHContainer & getLOHContainer() const {<br>
+    return const_cast<MCAssembler *>(this)->getLOHContainer();<br>
+  }<br>
+  /// @}<br>
   /// @name Backend Data Access<br>
   /// @{<br>
<br>
<br>
Added: llvm/trunk/include/llvm/MC/MCLinkerOptimizationHint.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCLinkerOptimizationHint.h?rev=205084&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCLinkerOptimizationHint.h?rev=205084&view=auto</a><br>


==============================================================================<br>
--- llvm/trunk/include/llvm/MC/MCLinkerOptimizationHint.h (added)<br>
+++ llvm/trunk/include/llvm/MC/MCLinkerOptimizationHint.h Sat Mar 29 02:34:53 2014<br>
@@ -0,0 +1,214 @@<br>
+//===- MCLinkerOptimizationHint.h - LOH interface ---------------*- C++ -*-===//<br>
+//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// This file declares some helpers classes to handle Linker Optimization Hint<br>
+// (LOH).<br>
+//<br>
+// FIXME: LOH interface supports only MachO format at the moment.<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#ifndef LLVM_MC_MCLINKEROPTIMIZATIONHINT_H<br>
+#define LLVM_MC_MCLINKEROPTIMIZATIONHINT_H<br>
+<br>
+#include "llvm/ADT/SmallVector.h"<br>
+#include "llvm/ADT/StringSwitch.h"<br>
+#include "llvm/ADT/StringRef.h"<br>
+#include "llvm/MC/MCMachObjectWriter.h"<br>
+#include "llvm/Support/raw_ostream.h"<br>
+<br>
+namespace llvm {<br>
+<br>
+// Forward declarations.<br>
+class MCAsmLayout;<br>
+class MCSymbol;<br>
+<br>
+/// Linker Optimization Hint Type.<br>
+enum MCLOHType {<br>
+  MCLOH_AdrpAdrp = 0x1u,      ///< Adrp xY, _v1@PAGE -> Adrp xY, _v2@PAGE.<br>
+  MCLOH_AdrpLdr = 0x2u,       ///< Adrp _v@PAGE -> Ldr _v@PAGEOFF.<br>
+  MCLOH_AdrpAddLdr = 0x3u,    ///< Adrp _v@PAGE -> Add _v@PAGEOFF -> Ldr.<br>
+  MCLOH_AdrpLdrGotLdr = 0x4u, ///< Adrp _v@GOTPAGE -> Ldr _v@GOTPAGEOFF -> Ldr.<br>
+  MCLOH_AdrpAddStr = 0x5u,    ///< Adrp _v@PAGE -> Add _v@PAGEOFF -> Str.<br>
+  MCLOH_AdrpLdrGotStr = 0x6u, ///< Adrp _v@GOTPAGE -> Ldr _v@GOTPAGEOFF -> Str.<br>
+  MCLOH_AdrpAdd = 0x7u,       ///< Adrp _v@PAGE -> Add _v@PAGEOFF.<br>
+  MCLOH_AdrpLdrGot = 0x8u     ///< Adrp _v@GOTPAGE -> Ldr _v@GOTPAGEOFF.<br>
+};<br>
+<br>
+static inline StringRef MCLOHDirectiveName() {<br>
+  return StringRef(".loh");<br>
+}<br>
+<br>
+static inline bool isValidMCLOHType(MCLOHType Kind) {<br>
+  return Kind >= MCLOH_AdrpAdrp && Kind <= MCLOH_AdrpLdrGot;<br>
+}<br>
+<br>
+static inline int MCLOHNameToId(StringRef Name) {<br>
+#define MCLOHCaseNameToId(Name)     .Case(#Name, MCLOH_ ## Name)<br>
+  return StringSwitch<int>(Name)<br>
+    MCLOHCaseNameToId(AdrpAdrp)<br>
+    MCLOHCaseNameToId(AdrpLdr)<br>
+    MCLOHCaseNameToId(AdrpAddLdr)<br>
+    MCLOHCaseNameToId(AdrpLdrGotLdr)<br>
+    MCLOHCaseNameToId(AdrpAddStr)<br>
+    MCLOHCaseNameToId(AdrpLdrGotStr)<br>
+    MCLOHCaseNameToId(AdrpAdd)<br>
+    MCLOHCaseNameToId(AdrpLdrGot)<br>
+    .Default(-1);<br>
+}<br>
+<br>
+static inline StringRef MCLOHIdToName(MCLOHType Kind) {<br>
+#define MCLOHCaseIdToName(Name)      case MCLOH_ ## Name: return StringRef(#Name);<br>
+  switch (Kind) {<br>
+    MCLOHCaseIdToName(AdrpAdrp);<br>
+    MCLOHCaseIdToName(AdrpLdr);<br>
+    MCLOHCaseIdToName(AdrpAddLdr);<br>
+    MCLOHCaseIdToName(AdrpLdrGotLdr);<br>
+    MCLOHCaseIdToName(AdrpAddStr);<br>
+    MCLOHCaseIdToName(AdrpLdrGotStr);<br>
+    MCLOHCaseIdToName(AdrpAdd);<br>
+    MCLOHCaseIdToName(AdrpLdrGot);<br>
+  }<br>
+  return StringRef();<br>
+}<br>
+<br>
+static inline int MCLOHIdToNbArgs(MCLOHType Kind) {<br>
+  switch (Kind) {<br>
+    // LOH with two arguments<br>
+  case MCLOH_AdrpAdrp:<br>
+  case MCLOH_AdrpLdr:<br>
+  case MCLOH_AdrpAdd:<br>
+  case MCLOH_AdrpLdrGot:<br>
+    return 2;<br>
+    // LOH with three arguments<br>
+  case MCLOH_AdrpAddLdr:<br>
+  case MCLOH_AdrpLdrGotLdr:<br>
+  case MCLOH_AdrpAddStr:<br>
+  case MCLOH_AdrpLdrGotStr:<br>
+    return 3;<br>
+  }<br>
+  return -1;<br>
+}<br>
+<br>
+/// Store Linker Optimization Hint information (LOH).<br>
+template<typename T><br>
+class LOHDirective {<br>
+private:<br>
+  MCLOHType Kind;<br>
+<br>
+  /// Arguments of this directive. Order matters.<br>
+  SmallVector<T *, 3> Args;<br>
+<br>
+  /// Emit this directive in @p OutStream using the information available<br>
+  /// in the given @p ObjWriter and @p Layout to get the address of the<br>
+  /// arguments within the object file.<br>
+  /// This function is currently specialized for T = MCSymbol.<br>
+  void Emit_impl(raw_ostream &OutStream, const MachObjectWriter &ObjWriter,<br>
+                 const MCAsmLayout &Layout) const {  }<br>
+<br>
+public:<br>
+  typedef SmallVectorImpl<T *> LOHArgs;<br>
+<br>
+  LOHDirective(MCLOHType Kind, const LOHArgs &Args)<br>
+  : Kind(Kind), Args(Args.begin(), Args.end()) {};<br>
+<br>
+  MCLOHType getKind() const { return Kind; }<br>
+<br>
+  const LOHArgs & getArgs() const { return Args; }<br>
+<br>
+  /// Emit this directive as:<br>
+  /// <kind, numArgs, addr1, ..., addrN><br>
+  void Emit(MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const {<br>
+    raw_ostream &OutStream = ObjWriter.getStream();<br>
+    Emit_impl(OutStream, ObjWriter, Layout);<br>
+  }<br>
+<br>
+  /// Get the size in bytes of this directive if emitted in @p ObjWriter with<br>
+  /// the given @p Layout.<br>
+  uint64_t getEmitSize(const MachObjectWriter &ObjWriter,<br>
+                       const MCAsmLayout &Layout) const {<br>
+    std::string Buffer;<br>
+    raw_string_ostream OutStream(Buffer);<br>
+    Emit_impl(OutStream, ObjWriter, Layout);<br>
+    return OutStream.tell();<br>
+  }<br>
+};<br>
+<br>
+template<typename T><br>
+class LOHContainer {<br>
+public:<br>
+  typedef SmallVectorImpl<LOHDirective<T> > LOHDirectives;<br>
+<br>
+private:<br>
+  /// Keep track of the emit size of all the LOHs.<br>
+  mutable uint64_t EmitSize;<br>
+<br>
+  /// Keep track of all LOH directives.<br>
+  SmallVector<LOHDirective<T>, 32> Directives;<br>
+<br>
+  /// Accessor to the directives.<br>
+  LOHDirectives &getDirectives() { return Directives; }<br>
+<br>
+public:<br>
+  LOHContainer() : EmitSize(0) {};<br>
+<br>
+  /// Const accessor to the directives.<br>
+  const LOHDirectives &getDirectives() const {<br>
+    return const_cast<LOHContainer *>(this)->getDirectives();<br>
+  }<br>
+<br>
+  /// Add the directive of the given kind @p Kind with the given arguments<br>
+  /// @p Args to the container.<br>
+  void addDirective(MCLOHType Kind,<br>
+                    const typename LOHDirective<T>::LOHArgs &Args) {<br>
+    assert(isValidMCLOHType(Kind) && "Invalid LOH directive type!");<br>
+    getDirectives().push_back(LOHDirective<T>(Kind, Args));<br>
+  }<br>
+<br>
+  /// Get the size of the directives if emitted.<br>
+  uint64_t getEmitSize(const MachObjectWriter &ObjWriter,<br>
+                       const MCAsmLayout &Layout) const {<br>
+    if (!EmitSize) {<br>
+      for (typename LOHDirectives::const_iterator It = getDirectives().begin(),<br>
+             EndIt = getDirectives().end(); It != EndIt; ++It)<br>
+        EmitSize += It->getEmitSize(ObjWriter, Layout);<br>
+    }<br>
+    return EmitSize;<br>
+  }<br>
+<br>
+  /// Emit all Linker Optimization Hint in one big table.<br>
+  /// Each line of the table is emitted by LOHDirective::Emit.<br>
+  void Emit(MachObjectWriter &ObjWriter, const MCAsmLayout &Layout) const {<br>
+    for (typename LOHDirectives::const_iterator It = getDirectives().begin(),<br>
+           EndIt = getDirectives().end(); It != EndIt; ++It)<br>
+      It->Emit(ObjWriter, Layout);<br>
+  }<br>
+<br>
+  void reset() {<br>
+    getDirectives().clear();<br>
+    EmitSize = 0;<br>
+  }<br>
+};<br>
+<br>
+// Add types for specialized template using MCSymbol.<br>
+typedef LOHDirective<MCSymbol> MCLOHDirective;<br>
+typedef LOHDirective<MCSymbol>::LOHArgs MCLOHArgs;<br>
+<br>
+typedef LOHContainer<MCLOHDirective>::LOHDirectives MCLOHDirectives;<br>
+<br>
+typedef LOHContainer<MCSymbol> MCLOHContainer;<br>
+<br>
+// Declare the specialization for MCSymbol.<br>
+template<><br>
+void MCLOHDirective::Emit_impl(raw_ostream &OutStream,<br>
+                               const MachObjectWriter &ObjWriter,<br>
+                               const MCAsmLayout &Layout) const;<br>
+} // end namespace llvm<br>
+<br>
+#endif<br>
<br>
Modified: llvm/trunk/include/llvm/MC/MCStreamer.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCStreamer.h?rev=205084&r1=205083&r2=205084&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/MC/MCStreamer.h?rev=205084&r1=205083&r2=205084&view=diff</a><br>


==============================================================================<br>
--- llvm/trunk/include/llvm/MC/MCStreamer.h (original)<br>
+++ llvm/trunk/include/llvm/MC/MCStreamer.h Sat Mar 29 02:34:53 2014<br>
@@ -19,6 +19,7 @@<br>
 #include "llvm/MC/MCAssembler.h"<br>
 #include "llvm/MC/MCDirectives.h"<br>
 #include "llvm/MC/MCDwarf.h"<br>
+#include "llvm/MC/MCLinkerOptimizationHint.h"<br>
 #include "llvm/MC/MCWin64EH.h"<br>
 #include "llvm/Support/DataTypes.h"<br>
 #include <string><br>
@@ -466,6 +467,10 @@ public:<br>
   ///<br>
   virtual void EmitELFSize(MCSymbol *Symbol, const MCExpr *Value) = 0;<br>
<br>
+  /// \brief Emit a Linker Optimization Hint (LOH) directive.<br>
+  /// \param Args - Arguments of the LOH.<br>
+  virtual void EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) {}<br>
+<br>
   /// EmitCommonSymbol - Emit a common symbol.<br>
   ///<br>
   /// @param Symbol - The common symbol to emit.<br>
<br>
Modified: llvm/trunk/include/llvm/Support/MachO.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/MachO.h?rev=205084&r1=205083&r2=205084&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Support/MachO.h?rev=205084&r1=205083&r2=205084&view=diff</a><br>


==============================================================================<br>
--- llvm/trunk/include/llvm/Support/MachO.h (original)<br>
+++ llvm/trunk/include/llvm/Support/MachO.h Sat Mar 29 02:34:53 2014<br>
@@ -128,7 +128,8 @@ namespace llvm {<br>
       LC_SOURCE_VERSION       = 0x0000002Au,<br>
       LC_DYLIB_CODE_SIGN_DRS  = 0x0000002Bu,<br>
       //                        0x0000002Cu,<br>
-      LC_LINKER_OPTIONS       = 0x0000002Du<br>
+      LC_LINKER_OPTIONS       = 0x0000002Du,<br>
+      LC_LINKER_OPTIMIZATION_HINT = 0x0000002Eu<br>
     };<br>
<br>
     enum : uint32_t {<br>
<br>
Modified: llvm/trunk/lib/MC/CMakeLists.txt<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/CMakeLists.txt?rev=205084&r1=205083&r2=205084&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/CMakeLists.txt?rev=205084&r1=205083&r2=205084&view=diff</a><br>


==============================================================================<br>
--- llvm/trunk/lib/MC/CMakeLists.txt (original)<br>
+++ llvm/trunk/lib/MC/CMakeLists.txt Sat Mar 29 02:34:53 2014<br>
@@ -24,6 +24,7 @@ add_llvm_library(LLVMMC<br>
   MCInstPrinter.cpp<br>
   MCInstrAnalysis.cpp<br>
   MCLabel.cpp<br>
+  MCLinkerOptimizationHint.cpp<br>
   MCMachOStreamer.cpp<br>
   MCMachObjectTargetWriter.cpp<br>
   MCModule.cpp<br>
<br>
Modified: llvm/trunk/lib/MC/MCAsmStreamer.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAsmStreamer.cpp?rev=205084&r1=205083&r2=205084&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAsmStreamer.cpp?rev=205084&r1=205083&r2=205084&view=diff</a><br>


==============================================================================<br>
--- llvm/trunk/lib/MC/MCAsmStreamer.cpp (original)<br>
+++ llvm/trunk/lib/MC/MCAsmStreamer.cpp Sat Mar 29 02:34:53 2014<br>
@@ -126,6 +126,7 @@ public:<br>
   void ChangeSection(const MCSection *Section,<br>
                      const MCExpr *Subsection) override;<br>
<br>
+  void EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) override;<br>
   void EmitLabel(MCSymbol *Symbol) override;<br>
   void EmitDebugLabel(MCSymbol *Symbol) override;<br>
<br>
@@ -342,6 +343,27 @@ void MCAsmStreamer::EmitLabel(MCSymbol *<br>
   EmitEOL();<br>
 }<br>
<br>
+void MCAsmStreamer::EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) {<br>
+  StringRef str = MCLOHIdToName(Kind);<br>
+<br>
+#ifndef NDEBUG<br>
+  int NbArgs = MCLOHIdToNbArgs(Kind);<br>
+  assert(NbArgs != -1 && ((size_t)NbArgs) == Args.size() && "Malformed LOH!");<br>
+  assert(str != "" && "Invalid LOH name");<br>
+#endif<br>
+<br>
+  OS << "\t" << MCLOHDirectiveName() << " " << str << "\t";<br>
+  bool IsFirst = true;<br>
+  for (MCLOHArgs::const_iterator It = Args.begin(), EndIt = Args.end();<br>
+       It != EndIt; ++It) {<br>
+    if (!IsFirst)<br>
+      OS << ", ";<br>
+    IsFirst = false;<br>
+    OS << **It;<br>
+  }<br>
+  EmitEOL();<br>
+}<br>
+<br>
 void MCAsmStreamer::EmitDebugLabel(MCSymbol *Symbol) {<br>
   assert(Symbol->isUndefined() && "Cannot define a symbol twice!");<br>
   MCStreamer::EmitDebugLabel(Symbol);<br>
<br>
Modified: llvm/trunk/lib/MC/MCAssembler.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAssembler.cpp?rev=205084&r1=205083&r2=205084&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCAssembler.cpp?rev=205084&r1=205083&r2=205084&view=diff</a><br>


==============================================================================<br>
--- llvm/trunk/lib/MC/MCAssembler.cpp (original)<br>
+++ llvm/trunk/lib/MC/MCAssembler.cpp Sat Mar 29 02:34:53 2014<br>
@@ -355,6 +355,7 @@ void MCAssembler::reset() {<br>
   getBackend().reset();<br>
   getEmitter().reset();<br>
   getWriter().reset();<br>
+  getLOHContainer().reset();<br>
 }<br>
<br>
 bool MCAssembler::isSymbolLinkerVisible(const MCSymbol &Symbol) const {<br>
<br>
Added: llvm/trunk/lib/MC/MCLinkerOptimizationHint.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCLinkerOptimizationHint.cpp?rev=205084&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCLinkerOptimizationHint.cpp?rev=205084&view=auto</a><br>


==============================================================================<br>
--- llvm/trunk/lib/MC/MCLinkerOptimizationHint.cpp (added)<br>
+++ llvm/trunk/lib/MC/MCLinkerOptimizationHint.cpp Sat Mar 29 02:34:53 2014<br>
@@ -0,0 +1,30 @@<br>
+//===-- llvm/MC/MCLinkerOptimizationHint.cpp ----- LOH handling -*- C++ -*-===//<br>
+//<br>
+//                     The LLVM Compiler Infrastructure<br>
+//<br>
+// This file is distributed under the University of Illinois Open Source<br>
+// License. See LICENSE.TXT for details.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#include "llvm/MC/MCLinkerOptimizationHint.h"<br>
+#include "llvm/MC/MCAsmLayout.h"<br>
+#include "llvm/Support/LEB128.h"<br>
+#include "llvm/MC/MCStreamer.h"<br>
+<br>
+using namespace llvm;<br>
+<br>
+namespace llvm {<br>
+template<><br>
+void MCLOHDirective::Emit_impl(raw_ostream &OutStream,<br>
+                               const MachObjectWriter &ObjWriter,<br>
+                               const MCAsmLayout &Layout) const {<br>
+  const MCAssembler &Asm = Layout.getAssembler();<br>
+  encodeULEB128(Kind, OutStream);<br>
+  encodeULEB128(Args.size(), OutStream);<br>
+  for (LOHArgs::const_iterator It = Args.begin(), EndIt = Args.end();<br>
+       It != EndIt; ++It)<br>
+    encodeULEB128(ObjWriter.getSymbolAddress(&Asm.getSymbolData(**It), Layout),<br>
+                  OutStream);<br>
+}<br>
+} // end namespace llvm<br>
<br>
Modified: llvm/trunk/lib/MC/MCMachOStreamer.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCMachOStreamer.cpp?rev=205084&r1=205083&r2=205084&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MCMachOStreamer.cpp?rev=205084&r1=205083&r2=205084&view=diff</a><br>


==============================================================================<br>
--- llvm/trunk/lib/MC/MCMachOStreamer.cpp (original)<br>
+++ llvm/trunk/lib/MC/MCMachOStreamer.cpp Sat Mar 29 02:34:53 2014<br>
@@ -17,6 +17,7 @@<br>
 #include "llvm/MC/MCDwarf.h"<br>
 #include "llvm/MC/MCExpr.h"<br>
 #include "llvm/MC/MCInst.h"<br>
+#include "llvm/MC/MCLinkerOptimizationHint.h"<br>
 #include "llvm/MC/MCMachOSymbolFlags.h"<br>
 #include "llvm/MC/MCObjectFileInfo.h"<br>
 #include "llvm/MC/MCObjectStreamer.h"<br>
@@ -104,6 +105,10 @@ public:<br>
     llvm_unreachable("macho doesn't support this directive");<br>
   }<br>
<br>
+  void EmitLOHDirective(MCLOHType Kind, const MCLOHArgs &Args) override {<br>
+    getAssembler().getLOHContainer().addDirective(Kind, Args);<br>
+  }<br>
+<br>
   void FinishImpl() override;<br>
 };<br>
<br>
<br>
Modified: llvm/trunk/lib/MC/MachObjectWriter.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MachObjectWriter.cpp?rev=205084&r1=205083&r2=205084&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/MC/MachObjectWriter.cpp?rev=205084&r1=205083&r2=205084&view=diff</a><br>


==============================================================================<br>
--- llvm/trunk/lib/MC/MachObjectWriter.cpp (original)<br>
+++ llvm/trunk/lib/MC/MachObjectWriter.cpp Sat Mar 29 02:34:53 2014<br>
@@ -761,6 +761,14 @@ void MachObjectWriter::WriteObject(MCAss<br>
     LoadCommandsSize += sizeof(MachO::linkedit_data_command);<br>
   }<br>
<br>
+  // Add the loh load command size, if used.<br>
+  uint64_t LOHRawSize = Asm.getLOHContainer().getEmitSize(*this, Layout);<br>
+  uint64_t LOHSize = RoundUpToAlignment(LOHRawSize, is64Bit() ? 8 : 4);<br>
+  if (LOHSize) {<br>
+    ++NumLoadCommands;<br>
+    LoadCommandsSize += sizeof(MachO::linkedit_data_command);<br>
+  }<br>
+<br>
   // Add the symbol table load command sizes, if used.<br>
   unsigned NumSymbols = LocalSymbolData.size() + ExternalSymbolData.size() +<br>
     UndefinedSymbolData.size();<br>
@@ -849,6 +857,12 @@ void MachObjectWriter::WriteObject(MCAss<br>
                              DataRegionsSize);<br>
   }<br>
<br>
+  // Write the loh load command, if used.<br>
+  uint64_t LOHTableEnd = DataInCodeTableEnd + LOHSize;<br>
+  if (LOHSize)<br>
+    WriteLinkeditLoadCommand(MachO::LC_LINKER_OPTIMIZATION_HINT,<br>
+                             DataInCodeTableEnd, LOHSize);<br>
+<br>
   // Write the symbol table load command, if used.<br>
   if (NumSymbols) {<br>
     unsigned FirstLocalSymbol = 0;<br>
@@ -865,10 +879,10 @@ void MachObjectWriter::WriteObject(MCAss<br>
<br>
     // If used, the indirect symbols are written after the section data.<br>
     if (NumIndirectSymbols)<br>
-      IndirectSymbolOffset = DataInCodeTableEnd;<br>
+      IndirectSymbolOffset = LOHTableEnd;<br>
<br>
     // The symbol table is written after the indirect symbol data.<br>
-    uint64_t SymbolTableOffset = DataInCodeTableEnd + IndirectSymbolSize;<br>
+    uint64_t SymbolTableOffset = LOHTableEnd + IndirectSymbolSize;<br>
<br>
     // The string table is written after symbol table.<br>
     uint64_t StringTableOffset =<br>
@@ -935,6 +949,17 @@ void MachObjectWriter::WriteObject(MCAss<br>
     Write16(Data->Kind);<br>
   }<br>
<br>
+  // Write out the loh commands, if there is one.<br>
+  if (LOHSize) {<br>
+#ifndef NDEBUG<br>
+    unsigned Start = OS.tell();<br>
+#endif<br>
+    Asm.getLOHContainer().Emit(*this, Layout);<br>
+    // Pad to a multiple of the pointer size.<br>
+    WriteBytes("", OffsetToAlignment(LOHRawSize, is64Bit() ? 8 : 4));<br>
+    assert(OS.tell() - Start == LOHSize);<br>
+  }<br>
+<br>
   // Write the symbol table data, if used.<br>
   if (NumSymbols) {<br>
     // Write the indirect symbol entries.<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div>