]> granicus.if.org Git - clang/commitdiff
Change embed-bitcode linkage type
authorSteven Wu <stevenwu@apple.com>
Mon, 16 May 2016 18:54:58 +0000 (18:54 +0000)
committerSteven Wu <stevenwu@apple.com>
Mon, 16 May 2016 18:54:58 +0000 (18:54 +0000)
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

lib/CodeGen/BackendUtil.cpp
test/Frontend/embed-bitcode.ll

index bffa621a596cef433c284ec95db8f81252539b9a..5a1db6c06819c8e36681ac4b11d52b6cecde0d86 100644 (file)
@@ -797,6 +797,20 @@ void clang::EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts,
   if (CGOpts.getEmbedBitcode() == CodeGenOptions::Embed_Off)
     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.
   std::string Data;
   ArrayRef<uint8_t> ModuleData;
@@ -820,38 +834,53 @@ void clang::EmbedBitcode(llvm::Module *M, const CodeGenOptions &CGOpts,
   }
   llvm::Constant *ModuleConstant =
       llvm::ConstantDataArray::get(M->getContext(), ModuleData);
-  // Use Appending linkage so it doesn't get optimized out.
   llvm::GlobalVariable *GV = new llvm::GlobalVariable(
-      *M, ModuleConstant->getType(), true, llvm::GlobalValue::AppendingLinkage,
+      *M, ModuleConstant->getType(), true, llvm::GlobalValue::PrivateLinkage,
       ModuleConstant);
   GV->setSection(getSectionNameForBitcode(T));
+  UsedArray.push_back(
+      ConstantExpr::getPointerBitCastOrAddrSpaceCast(GV, UsedElementType));
   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);
     Old->eraseFromParent();
   } else {
     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;
 
-  // 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");
 }
index 0bd75f1ac0d1865e5fc45ffe385ecd0d1036c689..bd2afb44bb0fdc7b0a2a6329f7be4c85b695add4 100644 (file)
 ; RUN:    -fembed-bitcode=all -x ir - -o /dev/null
 
 ; 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: section "__LLVM,__bitcode"
-; CHECK: @llvm.cmdline
+; CHECK: @llvm.cmdline = private constant
 ; CHECK: section "__LLVM,__cmdline"
 
 ; CHECK-ELF: @llvm.embedded.module
 ; CHECK-ELF: @llvm.cmdline
 ; 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: 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-MARKER: @llvm.embedded.module