瀏覽代碼

Change embed-bitcode linkage type

Embedded bitcode should have private linkage instead of appending or external.
Otherwise, it will cause link failure due to duplicated symbols.
Also add llvm.embedded.module and llvm.cmdline to llvm.compiler.used so they
don't get optimized out.

rdar://problem/21555860

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@269679 91177308-0d34-0410-b5e6-96231b3b80d8
Steven Wu 9 年之前
父節點
當前提交
27bf4de988
共有 2 個文件被更改,包括 55 次插入26 次删除
  1. 51 22
      lib/CodeGen/BackendUtil.cpp
  2. 4 4
      test/Frontend/embed-bitcode.ll

+ 51 - 22
lib/CodeGen/BackendUtil.cpp

@@ -797,6 +797,20 @@ void clang::EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts,
   if (CGOpts.getEmbedBitcode() == CodeGenOptions::Embed_Off)
   if (CGOpts.getEmbedBitcode() == CodeGenOptions::Embed_Off)
     return;
     return;
 
 
+  // Save llvm.compiler.used and remote it.
+  SmallVector<Constant*, 2> UsedArray;
+  SmallSet<GlobalValue*, 4> UsedGlobals;
+  Type *UsedElementType = Type::getInt8Ty(M->getContext())->getPointerTo(0);
+  GlobalVariable *Used = collectUsedGlobalVariables(*M, UsedGlobals, true);
+  for (auto *GV : UsedGlobals) {
+    if (GV->getName() != "llvm.embedded.module" &&
+        GV->getName() != "llvm.cmdline")
+      UsedArray.push_back(
+          ConstantExpr::getPointerBitCastOrAddrSpaceCast(GV, UsedElementType));
+  }
+  if (Used)
+    Used->eraseFromParent();
+
   // Embed the bitcode for the llvm module.
   // Embed the bitcode for the llvm module.
   std::string Data;
   std::string Data;
   ArrayRef<uint8_t> ModuleData;
   ArrayRef<uint8_t> ModuleData;
@@ -820,38 +834,53 @@ void clang::EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts,
   }
   }
   llvm::Constant *ModuleConstant =
   llvm::Constant *ModuleConstant =
       llvm::ConstantDataArray::get(M->getContext(), ModuleData);
       llvm::ConstantDataArray::get(M->getContext(), ModuleData);
-  // Use Appending linkage so it doesn't get optimized out.
   llvm::GlobalVariable *GV = new llvm::GlobalVariable(
   llvm::GlobalVariable *GV = new llvm::GlobalVariable(
-      *M, ModuleConstant->getType(), true, llvm::GlobalValue::AppendingLinkage,
+      *M, ModuleConstant->getType(), true, llvm::GlobalValue::PrivateLinkage,
       ModuleConstant);
       ModuleConstant);
   GV->setSection(getSectionNameForBitcode(T));
   GV->setSection(getSectionNameForBitcode(T));
+  UsedArray.push_back(
+      ConstantExpr::getPointerBitCastOrAddrSpaceCast(GV, UsedElementType));
   if (llvm::GlobalVariable *Old =
   if (llvm::GlobalVariable *Old =
-          M->getGlobalVariable("llvm.embedded.module")) {
-    assert(Old->use_empty() && "llvm.embedded.module must have no uses");
+          M->getGlobalVariable("llvm.embedded.module", true)) {
+    assert(Old->hasOneUse() &&
+           "llvm.embedded.module can only be used once in llvm.compiler.used");
     GV->takeName(Old);
     GV->takeName(Old);
     Old->eraseFromParent();
     Old->eraseFromParent();
   } else {
   } else {
     GV->setName("llvm.embedded.module");
     GV->setName("llvm.embedded.module");
   }
   }
 
 
-  // Return if only bitcode needs to be embedded.
-  if (CGOpts.getEmbedBitcode() == CodeGenOptions::Embed_Bitcode)
+  // Skip if only bitcode needs to be embedded.
+  if (CGOpts.getEmbedBitcode() != CodeGenOptions::Embed_Bitcode) {
+    // Embed command-line options.
+    ArrayRef<uint8_t> CmdData((uint8_t*)CGOpts.CmdArgs.data(),
+                              CGOpts.CmdArgs.size());
+    llvm::Constant *CmdConstant =
+      llvm::ConstantDataArray::get(M->getContext(), CmdData);
+    GV = new llvm::GlobalVariable(*M, CmdConstant->getType(), true,
+                                  llvm::GlobalValue::PrivateLinkage,
+                                  CmdConstant);
+    GV->setSection(getSectionNameForCommandline(T));
+    UsedArray.push_back(
+        ConstantExpr::getPointerBitCastOrAddrSpaceCast(GV, UsedElementType));
+    if (llvm::GlobalVariable *Old =
+            M->getGlobalVariable("llvm.cmdline", true)) {
+      assert(Old->hasOneUse() &&
+             "llvm.cmdline can only be used once in llvm.compiler.used");
+      GV->takeName(Old);
+      Old->eraseFromParent();
+    } else {
+      GV->setName("llvm.cmdline");
+    }
+  }
+
+  if (UsedArray.empty())
     return;
     return;
 
 
-  // Embed command-line options.
-  ArrayRef<uint8_t> CmdData((uint8_t*)CGOpts.CmdArgs.data(),
-                            CGOpts.CmdArgs.size());
-  llvm::Constant *CmdConstant =
-    llvm::ConstantDataArray::get(M->getContext(), CmdData);
-  GV = new llvm::GlobalVariable(*M, CmdConstant->getType(), true,
-                                llvm::GlobalValue::AppendingLinkage,
-                                CmdConstant);
-  GV->setSection(getSectionNameForCommandline(T));
-  if (llvm::GlobalVariable *Old = M->getGlobalVariable("llvm.cmdline")) {
-    assert(Old->use_empty() && "llvm.cmdline must have no uses");
-    GV->takeName(Old);
-    Old->eraseFromParent();
-  } else {
-    GV->setName("llvm.cmdline");
-  }
+  // Recreate llvm.compiler.used.
+  ArrayType *ATy = ArrayType::get(UsedElementType, UsedArray.size());
+  auto *NewUsed = new GlobalVariable(
+      *M, ATy, false, llvm::GlobalValue::AppendingLinkage,
+      llvm::ConstantArray::get(ATy, UsedArray), "llvm.compiler.used");
+  NewUsed->setSection("llvm.metadata");
 }
 }

+ 4 - 4
test/Frontend/embed-bitcode.ll

@@ -31,10 +31,10 @@
 ; RUN:    -fembed-bitcode=all -x ir - -o /dev/null
 ; RUN:    -fembed-bitcode=all -x ir - -o /dev/null
 
 
 ; check the magic number of bitcode at the beginning of the string
 ; check the magic number of bitcode at the beginning of the string
-; CHECK: @llvm.embedded.module
+; CHECK: @llvm.embedded.module = private constant
 ; CHECK: c"\DE\C0\17\0B
 ; CHECK: c"\DE\C0\17\0B
 ; CHECK: section "__LLVM,__bitcode"
 ; CHECK: section "__LLVM,__bitcode"
-; CHECK: @llvm.cmdline
+; CHECK: @llvm.cmdline = private constant
 ; CHECK: section "__LLVM,__cmdline"
 ; CHECK: section "__LLVM,__cmdline"
 
 
 ; CHECK-ELF: @llvm.embedded.module
 ; CHECK-ELF: @llvm.embedded.module
@@ -42,10 +42,10 @@
 ; CHECK-ELF: @llvm.cmdline
 ; CHECK-ELF: @llvm.cmdline
 ; CHECK-ELF: section ".llvmcmd"
 ; CHECK-ELF: section ".llvmcmd"
 
 
-; CHECK-ONLY-BITCODE: @llvm.embedded.module
+; CHECK-ONLY-BITCODE: @llvm.embedded.module = private constant
 ; CHECK-ONLY-BITCODE: c"\DE\C0\17\0B
 ; CHECK-ONLY-BITCODE: c"\DE\C0\17\0B
 ; CHECK-ONLY-BITCODE: section "__LLVM,__bitcode"
 ; CHECK-ONLY-BITCODE: section "__LLVM,__bitcode"
-; CHECK-ONLY-BITCODE-NOT: @llvm.cmdline
+; CHECK-ONLY-BITCODE-NOT: @llvm.cmdline = private constant
 ; CHECK-ONLY-BITCODE-NOT: section "__LLVM,__cmdline"
 ; CHECK-ONLY-BITCODE-NOT: section "__LLVM,__cmdline"
 
 
 ; CHECK-MARKER: @llvm.embedded.module
 ; CHECK-MARKER: @llvm.embedded.module