[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