[PATCH] D31352: Linker: Mark non-prevailing dllexport symbols as exported with a linker flag.
Rafael Avila de Espindola via llvm-commits
llvm-commits at lists.llvm.org
Fri Mar 24 14:14:13 PDT 2017
This has the disadvantage that now two parts of the llvm are responsible
for converting dllexport to linker directives (even if they share the
function they call).
I would prefer your previous solution or for the linker to keep a
dllexport declaration in the IR.
Cheers,
Rafael
Peter Collingbourne via Phabricator <reviews at reviews.llvm.org> writes:
> pcc created this revision.
> Herald added a subscriber: mehdi_amini.
>
> Fixes PR32334.
>
>
> https://reviews.llvm.org/D31352
>
> Files:
> llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
> llvm/include/llvm/IR/Mangler.h
> llvm/include/llvm/Target/TargetLoweringObjectFile.h
> llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
> llvm/lib/IR/Mangler.cpp
> llvm/lib/LTO/LTO.cpp
> llvm/lib/LTO/LTOModule.cpp
> llvm/lib/Linker/IRMover.cpp
> llvm/test/LTO/Resolution/X86/dllexport.ll
>
> Index: llvm/test/LTO/Resolution/X86/dllexport.ll
> ===================================================================
> --- /dev/null
> +++ llvm/test/LTO/Resolution/X86/dllexport.ll
> @@ -0,0 +1,23 @@
> +; RUN: llvm-as %s -o %t.o
> +; RUN: llvm-lto2 -o %t2.o %t.o -r %t.o,f,x -r %t.o,g,x -r %t.o,a,x -save-temps
> +; RUN: llvm-dis < %t2.o.0.0.preopt.bc -o - | FileCheck %s
> +
> +; CHECK-NOT: alias
> +; CHECK-NOT: global
> +; CHECK-NOT: void
> +
> +; CHECK: !llvm.linker.options = !{!0, !1, !2}
> +; CHECK: !0 = !{!" /EXPORT:f"}
> +; CHECK: !1 = !{!" /EXPORT:g,DATA"}
> +; CHECK: !2 = !{!" /EXPORT:a,DATA"}
> +
> +target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
> +target triple = "x86_64-pc-windows-msvc"
> +
> + at a = dllexport alias i8, i8* @g
> +
> + at g = dllexport global i8 0
> +
> +define dllexport void @f() {
> + ret void
> +}
> Index: llvm/lib/Linker/IRMover.cpp
> ===================================================================
> --- llvm/lib/Linker/IRMover.cpp
> +++ llvm/lib/Linker/IRMover.cpp
> @@ -17,6 +17,7 @@
> #include "llvm/IR/DiagnosticPrinter.h"
> #include "llvm/IR/GVMaterializer.h"
> #include "llvm/IR/Intrinsics.h"
> +#include "llvm/IR/Mangler.h"
> #include "llvm/IR/TypeFinder.h"
> #include "llvm/Support/Error.h"
> #include "llvm/Transforms/Utils/Cloning.h"
> @@ -486,6 +487,7 @@
> /// module.
> void prepareCompileUnitsForImport();
> void linkNamedMDNodes();
> + void linkCOFFDLLExportFlags();
>
> public:
> IRLinker(Module &DstM, MDMapT &SharedMDs,
> @@ -1087,6 +1089,30 @@
> }
> }
>
> +/// COFF-specific: link dropped dllexport flags into DstM using metadata.
> +void IRLinker::linkCOFFDLLExportFlags() {
> + auto *MD = DstM.getOrInsertNamedMetadata("llvm.linker.options");
> + Mangler Mang;
> + auto LinkFlag = [&](GlobalValue *GV) {
> + if (!GV->hasDLLExportStorageClass() || GV->isDeclaration() ||
> + ValuesToLink.count(GV))
> + return;
> +
> + std::string Flag;
> + raw_string_ostream OS(Flag);
> + Mang.getCOFFDLLExportLinkerFlag(OS, GV);
> + MD->addOperand(MDNode::get(GV->getContext(),
> + {MDString::get(GV->getContext(), OS.str())}));
> + };
> +
> + for (auto &F : *SrcM)
> + LinkFlag(&F);
> + for (auto &GV : SrcM->globals())
> + LinkFlag(&GV);
> + for (auto &GA : SrcM->aliases())
> + LinkFlag(&GA);
> +}
> +
> /// Merge the linker flags in Src into the Dest module.
> Error IRLinker::linkModuleFlagsMetadata() {
> // If the source module has no module flags, we are done.
> @@ -1332,6 +1358,10 @@
> // are properly remapped.
> linkNamedMDNodes();
>
> + // COFF-specific: link dropped dllexport flags into DstM.
> + if (SrcTriple.isOSBinFormatCOFF())
> + linkCOFFDLLExportFlags();
> +
> // Merge the module flags into the DstM module.
> return linkModuleFlagsMetadata();
> }
> Index: llvm/lib/LTO/LTOModule.cpp
> ===================================================================
> --- llvm/lib/LTO/LTOModule.cpp
> +++ llvm/lib/LTO/LTOModule.cpp
> @@ -656,7 +656,7 @@
> for (const NameAndAttributes &Sym : _symbols) {
> if (!Sym.symbol)
> continue;
> - emitLinkerFlagsForGlobalCOFF(OS, Sym.symbol, TT, M);
> + M.getCOFFDLLExportLinkerFlag(OS, Sym.symbol);
> }
>
> // Add other interesting metadata here.
> Index: llvm/lib/LTO/LTO.cpp
> ===================================================================
> --- llvm/lib/LTO/LTO.cpp
> +++ llvm/lib/LTO/LTO.cpp
> @@ -395,7 +395,7 @@
> Mangler M;
> for (const ModuleSymbolTable::Symbol &Sym : SymTab.symbols())
> if (auto *GV = Sym.dyn_cast<GlobalValue*>())
> - emitLinkerFlagsForGlobalCOFF(LOS, GV, TT, M);
> + M.getCOFFDLLExportLinkerFlag(LOS, GV);
> LOS.flush();
> return LinkerOpts;
> }
> Index: llvm/lib/IR/Mangler.cpp
> ===================================================================
> --- llvm/lib/IR/Mangler.cpp
> +++ llvm/lib/IR/Mangler.cpp
> @@ -13,6 +13,7 @@
>
> #include "llvm/IR/Mangler.h"
> #include "llvm/ADT/SmallString.h"
> +#include "llvm/ADT/Triple.h"
> #include "llvm/ADT/Twine.h"
> #include "llvm/IR/DataLayout.h"
> #include "llvm/IR/DerivedTypes.h"
> @@ -172,3 +173,35 @@
> raw_svector_ostream OS(OutName);
> getNameWithPrefix(OS, GV, CannotUsePrivateLabel);
> }
> +
> +void Mangler::getCOFFDLLExportLinkerFlag(raw_ostream &OS,
> + const GlobalValue *GV) {
> + if (!GV->hasDLLExportStorageClass() || GV->isDeclaration())
> + return;
> +
> + Triple TT(GV->getParent()->getTargetTriple());
> + if (TT.isKnownWindowsMSVCEnvironment())
> + OS << " /EXPORT:";
> + else
> + OS << " -export:";
> +
> + if (TT.isWindowsGNUEnvironment() || TT.isWindowsCygwinEnvironment()) {
> + std::string Flag;
> + raw_string_ostream FlagOS(Flag);
> + getNameWithPrefix(FlagOS, GV, false);
> + FlagOS.flush();
> + if (Flag[0] == GV->getParent()->getDataLayout().getGlobalPrefix())
> + OS << Flag.substr(1);
> + else
> + OS << Flag;
> + } else {
> + getNameWithPrefix(OS, GV, false);
> + }
> +
> + if (!GV->getValueType()->isFunctionTy()) {
> + if (TT.isKnownWindowsMSVCEnvironment())
> + OS << ",DATA";
> + else
> + OS << ",data";
> + }
> +}
> Index: llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
> ===================================================================
> --- llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
> +++ llvm/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
> @@ -967,37 +967,6 @@
> 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;
> @@ -1194,7 +1163,8 @@
>
> void TargetLoweringObjectFileCOFF::emitLinkerFlagsForGlobal(
> raw_ostream &OS, const GlobalValue *GV) const {
> - emitLinkerFlagsForGlobalCOFF(OS, GV, getTargetTriple(), getMangler());
> + Mangler Mang;
> + Mang.getCOFFDLLExportLinkerFlag(OS, GV);
> }
>
> //===----------------------------------------------------------------------===//
> Index: llvm/include/llvm/Target/TargetLoweringObjectFile.h
> ===================================================================
> --- llvm/include/llvm/Target/TargetLoweringObjectFile.h
> +++ llvm/include/llvm/Target/TargetLoweringObjectFile.h
> @@ -180,9 +180,6 @@
> return nullptr;
> }
>
> - virtual void emitLinkerFlagsForGlobal(raw_ostream &OS,
> - const GlobalValue *GV) const {}
> -
> protected:
> virtual MCSection *SelectSectionForGlobal(const GlobalObject *GO,
> SectionKind Kind,
> Index: llvm/include/llvm/IR/Mangler.h
> ===================================================================
> --- llvm/include/llvm/IR/Mangler.h
> +++ llvm/include/llvm/IR/Mangler.h
> @@ -44,6 +44,10 @@
> const DataLayout &DL);
> static void getNameWithPrefix(SmallVectorImpl<char> &OutName,
> const Twine &GVName, const DataLayout &DL);
> +
> + /// Print an appropriate linker flag for exporting this symbol on COFF
> + /// targets.
> + void getCOFFDLLExportLinkerFlag(raw_ostream &OS, const GlobalValue *GV);
> };
>
> } // End llvm namespace
> Index: llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
> ===================================================================
> --- llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
> +++ llvm/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
> @@ -158,7 +158,7 @@
> const MCSymbol *KeySym) const override;
>
> void emitLinkerFlagsForGlobal(raw_ostream &OS,
> - const GlobalValue *GV) const override;
> + const GlobalValue *GV) const;
> };
>
> class TargetLoweringObjectFileWasm : public TargetLoweringObjectFile {
> @@ -184,9 +184,6 @@
> const TargetMachine &TM) const override;
> };
>
> -void emitLinkerFlagsForGlobalCOFF(raw_ostream &OS, const GlobalValue *GV,
> - const Triple &TT, Mangler &Mangler);
> -
> } // end namespace llvm
>
> #endif // LLVM_CODEGEN_TARGETLOWERINGOBJECTFILEIMPL_H
More information about the llvm-commits
mailing list