]> granicus.if.org Git - llvm/commitdiff
[lto] add getLinkerOpts()
authorBob Haarman <llvm@inglorion.net>
Thu, 2 Feb 2017 23:00:49 +0000 (23:00 +0000)
committerBob Haarman <llvm@inglorion.net>
Thu, 2 Feb 2017 23:00:49 +0000 (23:00 +0000)
Summary: Some compilers, including MSVC and Clang, allow linker options to be specified in source files. In the legacy LTO API, there is a getLinkerOpts() method that returns linker options for the bitcode module being processed. This change adds that method to the new API, so that the COFF linker can get the right linker options when using the new LTO API.

Reviewers: pcc, ruiu, mehdi_amini, tejohnson

Reviewed By: pcc

Differential Revision: https://reviews.llvm.org/D29207

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@293950 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
include/llvm/LTO/LTO.h
lib/CodeGen/TargetLoweringObjectFileImpl.cpp
lib/LTO/LTO.cpp

index cc71fa3918a1332278380dbb6cb898a7aca20dab..f2519af383ba3bec841369a84d4d26f644266290 100644 (file)
@@ -171,6 +171,9 @@ public:
                                 const GlobalValue *GV) const override;
 };
 
+void emitLinkerFlagsForGlobalCOFF(raw_ostream &OS, const GlobalValue *GV,
+                                  const Triple &TT, Mangler &Mangler);
+
 } // end namespace llvm
 
 #endif
index 57b5e50e40d9192b88b0020c5b84f3b9134b6910..5886ed9917191ddcdafc35ea1abe14b3e64b59a1 100644 (file)
@@ -25,6 +25,7 @@
 #include "llvm/LTO/Config.h"
 #include "llvm/Linker/IRMover.h"
 #include "llvm/Object/IRObjectFile.h"
+#include "llvm/Support/Error.h"
 #include "llvm/Support/thread.h"
 #include "llvm/Target/TargetOptions.h"
 #include "llvm/Transforms/IPO/FunctionImport.h"
@@ -226,6 +227,9 @@ public:
         symbol_iterator(SymTab.symbols().end(), SymTab, this));
   }
 
+  /// Returns linker options specified in the input file.
+  Expected<std::string> getLinkerOpts();
+
   /// Returns the path to the InputFile.
   StringRef getName() const;
 
index eb2a28f574a5449b45e9fa7821a5777a271d7088..6d45add71dcf859277077f7dd3108dc0a549406c 100644 (file)
@@ -919,6 +919,37 @@ static int getSelectionForCOFF(const GlobalValue *GV) {
   return 0;
 }
 
+void llvm::emitLinkerFlagsForGlobalCOFF(raw_ostream &OS, const GlobalValue *GV,
+                                        const Triple &TT, Mangler &Mangler) {
+  if (!GV->hasDLLExportStorageClass() || GV->isDeclaration())
+    return;
+
+  if (TT.isKnownWindowsMSVCEnvironment())
+    OS << " /EXPORT:";
+  else
+    OS << " -export:";
+
+  if (TT.isWindowsGNUEnvironment() || TT.isWindowsCygwinEnvironment()) {
+    std::string Flag;
+    raw_string_ostream FlagOS(Flag);
+    Mangler.getNameWithPrefix(FlagOS, GV, false);
+    FlagOS.flush();
+    if (Flag[0] == GV->getParent()->getDataLayout().getGlobalPrefix())
+      OS << Flag.substr(1);
+    else
+      OS << Flag;
+  } else {
+    Mangler.getNameWithPrefix(OS, GV, false);
+  }
+
+  if (!GV->getValueType()->isFunctionTy()) {
+    if (TT.isKnownWindowsMSVCEnvironment())
+      OS << ",DATA";
+    else
+      OS << ",data";
+  }
+}
+
 MCSection *TargetLoweringObjectFileCOFF::getExplicitSectionGlobal(
     const GlobalObject *GO, SectionKind Kind, const TargetMachine &TM) const {
   int Selection = 0;
@@ -1122,33 +1153,5 @@ MCSection *TargetLoweringObjectFileCOFF::getStaticDtorSection(
 
 void TargetLoweringObjectFileCOFF::emitLinkerFlagsForGlobal(
     raw_ostream &OS, const GlobalValue *GV) const {
-  if (!GV->hasDLLExportStorageClass() || GV->isDeclaration())
-    return;
-
-  const Triple &TT = getTargetTriple();
-
-  if (TT.isKnownWindowsMSVCEnvironment())
-    OS << " /EXPORT:";
-  else
-    OS << " -export:";
-
-  if (TT.isWindowsGNUEnvironment() || TT.isWindowsCygwinEnvironment()) {
-    std::string Flag;
-    raw_string_ostream FlagOS(Flag);
-    getMangler().getNameWithPrefix(FlagOS, GV, false);
-    FlagOS.flush();
-    if (Flag[0] == GV->getParent()->getDataLayout().getGlobalPrefix())
-      OS << Flag.substr(1);
-    else
-      OS << Flag;
-  } else {
-    getMangler().getNameWithPrefix(OS, GV, false);
-  }
-
-  if (!GV->getValueType()->isFunctionTy()) {
-    if (TT.isKnownWindowsMSVCEnvironment())
-      OS << ",DATA";
-    else
-      OS << ",data";
-  }
+  emitLinkerFlagsForGlobalCOFF(OS, GV, getTargetTriple(), getMangler());
 }
index 51b7e7d13c75e7e6afb93fd559a40f161cf6185f..db0253161b8d11282275dda07650045c07676c64 100644 (file)
 #include "llvm/Bitcode/BitcodeReader.h"
 #include "llvm/Bitcode/BitcodeWriter.h"
 #include "llvm/CodeGen/Analysis.h"
+#include "llvm/CodeGen/TargetLoweringObjectFileImpl.h"
 #include "llvm/IR/AutoUpgrade.h"
 #include "llvm/IR/DiagnosticPrinter.h"
 #include "llvm/IR/LegacyPassManager.h"
+#include "llvm/IR/Mangler.h"
+#include "llvm/IR/Metadata.h"
 #include "llvm/LTO/LTOBackend.h"
 #include "llvm/Linker/IRMover.h"
 #include "llvm/Object/ModuleSummaryIndexObjectFile.h"
+#include "llvm/Support/Error.h"
 #include "llvm/Support/ManagedStatic.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Path.h"
@@ -291,6 +295,32 @@ Expected<int> InputFile::Symbol::getComdatIndex() const {
   return -1;
 }
 
+Expected<std::string> InputFile::getLinkerOpts() {
+  std::string LinkerOpts;
+  raw_string_ostream LOS(LinkerOpts);
+  // Extract linker options from module metadata.
+  for (InputModule &Mod : Mods) {
+    std::unique_ptr<Module> &M = Mod.Mod;
+    if (auto E = M->materializeMetadata())
+      return std::move(E);
+    if (Metadata *Val = M->getModuleFlag("Linker Options")) {
+      MDNode *LinkerOptions = cast<MDNode>(Val);
+      for (const MDOperand &MDOptions : LinkerOptions->operands())
+        for (const MDOperand &MDOption : cast<MDNode>(MDOptions)->operands())
+          LOS << " " << cast<MDString>(MDOption)->getString();
+    }
+  }
+
+  // Synthesize export flags for symbols with dllexport storage.
+  const Triple TT(Mods[0].Mod->getTargetTriple());
+  Mangler M;
+  for (const ModuleSymbolTable::Symbol &Sym : SymTab.symbols())
+    if (auto *GV = Sym.dyn_cast<GlobalValue*>())
+      emitLinkerFlagsForGlobalCOFF(LOS, GV, TT, M);
+  LOS.flush();
+  return LinkerOpts;
+}
+
 StringRef InputFile::getName() const {
   return Mods[0].BM.getModuleIdentifier();
 }