From: Bob Haarman Date: Thu, 2 Feb 2017 23:00:49 +0000 (+0000) Subject: [lto] add getLinkerOpts() X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=ea59150166481a10a2d698639f146af4a97f073d;p=llvm [lto] add getLinkerOpts() 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 --- diff --git a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h index cc71fa3918a..f2519af383b 100644 --- a/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h +++ b/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h @@ -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 diff --git a/include/llvm/LTO/LTO.h b/include/llvm/LTO/LTO.h index 57b5e50e40d..5886ed99171 100644 --- a/include/llvm/LTO/LTO.h +++ b/include/llvm/LTO/LTO.h @@ -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 getLinkerOpts(); + /// Returns the path to the InputFile. StringRef getName() const; diff --git a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp index eb2a28f574a..6d45add71dc 100644 --- a/lib/CodeGen/TargetLoweringObjectFileImpl.cpp +++ b/lib/CodeGen/TargetLoweringObjectFileImpl.cpp @@ -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()); } diff --git a/lib/LTO/LTO.cpp b/lib/LTO/LTO.cpp index 51b7e7d13c7..db0253161b8 100644 --- a/lib/LTO/LTO.cpp +++ b/lib/LTO/LTO.cpp @@ -17,12 +17,16 @@ #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 InputFile::Symbol::getComdatIndex() const { return -1; } +Expected InputFile::getLinkerOpts() { + std::string LinkerOpts; + raw_string_ostream LOS(LinkerOpts); + // Extract linker options from module metadata. + for (InputModule &Mod : Mods) { + std::unique_ptr &M = Mod.Mod; + if (auto E = M->materializeMetadata()) + return std::move(E); + if (Metadata *Val = M->getModuleFlag("Linker Options")) { + MDNode *LinkerOptions = cast(Val); + for (const MDOperand &MDOptions : LinkerOptions->operands()) + for (const MDOperand &MDOption : cast(MDOptions)->operands()) + LOS << " " << cast(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()) + emitLinkerFlagsForGlobalCOFF(LOS, GV, TT, M); + LOS.flush(); + return LinkerOpts; +} + StringRef InputFile::getName() const { return Mods[0].BM.getModuleIdentifier(); }