[llvm] r323017 - CodeGen: handle llvm.used properly for COFF

Saleem Abdulrasool via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 19 16:28:03 PST 2018


Author: compnerd
Date: Fri Jan 19 16:28:02 2018
New Revision: 323017

URL: http://llvm.org/viewvc/llvm-project?rev=323017&view=rev
Log:
CodeGen: handle llvm.used properly for COFF

`llvm.used` contains a list of pointers to named values which the
compiler, assembler, and linker are required to treat as if there is a
reference that they cannot see.  Ensure that the symbols are preserved
by adding an explicit `-include` reference to the linker command.

Added:
    llvm/trunk/test/CodeGen/X86/coff-no-dead-strip.ll
Modified:
    llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFile.h
    llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
    llvm/trunk/include/llvm/IR/Mangler.h
    llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
    llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
    llvm/trunk/lib/IR/Mangler.cpp

Modified: llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFile.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFile.h?rev=323017&r1=323016&r2=323017&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFile.h (original)
+++ llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFile.h Fri Jan 19 16:28:02 2018
@@ -183,6 +183,9 @@ public:
   virtual void emitLinkerFlagsForGlobal(raw_ostream &OS,
                                         const GlobalValue *GV) const {}
 
+  virtual void emitLinkerFlagsForUsed(raw_ostream &OS,
+                                      const GlobalValue *GV) const {}
+
 protected:
   virtual MCSection *SelectSectionForGlobal(const GlobalObject *GO,
                                             SectionKind Kind,

Modified: llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h?rev=323017&r1=323016&r2=323017&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h (original)
+++ llvm/trunk/include/llvm/CodeGen/TargetLoweringObjectFileImpl.h Fri Jan 19 16:28:02 2018
@@ -163,6 +163,9 @@ public:
 
   void emitLinkerFlagsForGlobal(raw_ostream &OS,
                                 const GlobalValue *GV) const override;
+
+  void emitLinkerFlagsForUsed(raw_ostream &OS,
+                              const GlobalValue *GV) const override;
 };
 
 class TargetLoweringObjectFileWasm : public TargetLoweringObjectFile {

Modified: llvm/trunk/include/llvm/IR/Mangler.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Mangler.h?rev=323017&r1=323016&r2=323017&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Mangler.h (original)
+++ llvm/trunk/include/llvm/IR/Mangler.h Fri Jan 19 16:28:02 2018
@@ -50,6 +50,9 @@ public:
 void emitLinkerFlagsForGlobalCOFF(raw_ostream &OS, const GlobalValue *GV,
                                   const Triple &TT, Mangler &Mangler);
 
+void emitLinkerFlagsForUsedCOFF(raw_ostream &OS, const GlobalValue *GV,
+                                const Triple &T, Mangler &M);
+
 } // End llvm namespace
 
 #endif

Modified: llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp?rev=323017&r1=323016&r2=323017&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp (original)
+++ llvm/trunk/lib/CodeGen/AsmPrinter/AsmPrinter.cpp Fri Jan 19 16:28:02 2018
@@ -1434,6 +1434,7 @@ bool AsmPrinter::doFinalization(Module &
     // Emit /EXPORT: flags for each exported global as necessary.
     const auto &TLOF = getObjFileLowering();
     std::string Flags;
+
     for (const GlobalValue &GV : M.global_values()) {
       raw_string_ostream OS(Flags);
       TLOF.emitLinkerFlagsForGlobal(OS, &GV);
@@ -1444,6 +1445,35 @@ bool AsmPrinter::doFinalization(Module &
       }
       Flags.clear();
     }
+
+    // Emit /INCLUDE: flags for each used global as necessary.
+    if (const auto *LU = M.getNamedGlobal("llvm.used")) {
+      assert(LU->hasInitializer() &&
+             "expected llvm.used to have an initializer");
+      assert(isa<ArrayType>(LU->getValueType()) &&
+             "expected llvm.used to be an array type");
+      if (const auto *A = cast<ConstantArray>(LU->getInitializer())) {
+        for (const Value *Op : A->operands()) {
+          const auto *GV =
+              cast<GlobalValue>(Op->stripPointerCastsNoFollowAliases());
+          // Global symbols with internal linkage are not visible to the linker,
+          // and thus would cause an error when the linker tried to preserve the
+          // symbol due to the `/include:` directive.
+          if (GV->hasInternalLinkage())
+            continue;
+
+          raw_string_ostream OS(Flags);
+          TLOF.emitLinkerFlagsForUsed(OS, GV);
+          OS.flush();
+
+          if (!Flags.empty()) {
+            OutStreamer->SwitchSection(TLOF.getDrectveSection());
+            OutStreamer->EmitBytes(Flags);
+          }
+          Flags.clear();
+        }
+      }
+    }
   }
 
   // Allow the target to emit any magic that it wants at the end of the file,

Modified: llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp?rev=323017&r1=323016&r2=323017&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp (original)
+++ llvm/trunk/lib/CodeGen/TargetLoweringObjectFileImpl.cpp Fri Jan 19 16:28:02 2018
@@ -1250,6 +1250,11 @@ void TargetLoweringObjectFileCOFF::emitL
   emitLinkerFlagsForGlobalCOFF(OS, GV, getTargetTriple(), getMangler());
 }
 
+void TargetLoweringObjectFileCOFF::emitLinkerFlagsForUsed(
+    raw_ostream &OS, const GlobalValue *GV) const {
+  emitLinkerFlagsForUsedCOFF(OS, GV, getTargetTriple(), getMangler());
+}
+
 //===----------------------------------------------------------------------===//
 //                                  Wasm
 //===----------------------------------------------------------------------===//

Modified: llvm/trunk/lib/IR/Mangler.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Mangler.cpp?rev=323017&r1=323016&r2=323017&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Mangler.cpp (original)
+++ llvm/trunk/lib/IR/Mangler.cpp Fri Jan 19 16:28:02 2018
@@ -204,3 +204,13 @@ void llvm::emitLinkerFlagsForGlobalCOFF(
       OS << ",data";
   }
 }
+
+void llvm::emitLinkerFlagsForUsedCOFF(raw_ostream &OS, const GlobalValue *GV,
+                                      const Triple &T, Mangler &M) {
+  if (!T.isKnownWindowsMSVCEnvironment())
+    return;
+
+  OS << " /INCLUDE:";
+  M.getNameWithPrefix(OS, GV, false);
+}
+

Added: llvm/trunk/test/CodeGen/X86/coff-no-dead-strip.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/coff-no-dead-strip.ll?rev=323017&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/coff-no-dead-strip.ll (added)
+++ llvm/trunk/test/CodeGen/X86/coff-no-dead-strip.ll Fri Jan 19 16:28:02 2018
@@ -0,0 +1,20 @@
+; RUN: llc -mtriple i686-windows-msvc -filetype asm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-ULP
+; RUN: llc -mtriple x86_64-windows-msvc -filetype asm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-NOULP
+; RUN: llc -mtriple thumbv7-windows-msvc -filetype asm -o - %s | FileCheck %s -check-prefix CHECK -check-prefix CHECK-NOULP
+
+ at i = global i32 0
+ at j = weak global i32 0
+ at k = internal global i32 0
+declare x86_vectorcallcc void @l()
+
+ at llvm.used = appending global [4 x i8*] [i8* bitcast (i32* @i to i8*), i8* bitcast (i32* @j to i8*), i8* bitcast (i32* @k to i8*), i8* bitcast (void ()* @l to i8*)]
+
+; CHECK: .section .drectve
+; CHECK-ULP: .ascii " /INCLUDE:_i"
+; CHECK-ULP: .ascii " /INCLUDE:_j"
+; CHECK-ULP-NOT: .ascii " /INCLUDE:_k"
+; CHECK-NOULP: .ascii " /INCLUDE:i"
+; CHECK-NOULP: .ascii " /INCLUDE:j"
+; CHECK-NOULP-NOT: .ascii " /INCLUDE:k"
+; CHECK: .ascii " /INCLUDE:l@@0"
+




More information about the llvm-commits mailing list