r269679 - Change embed-bitcode linkage type

Steven Wu via cfe-commits cfe-commits at lists.llvm.org
Mon May 16 11:54:59 PDT 2016


Author: steven_wu
Date: Mon May 16 13:54:58 2016
New Revision: 269679

URL: http://llvm.org/viewvc/llvm-project?rev=269679&view=rev
Log:
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

Modified:
    cfe/trunk/lib/CodeGen/BackendUtil.cpp
    cfe/trunk/test/Frontend/embed-bitcode.ll

Modified: cfe/trunk/lib/CodeGen/BackendUtil.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/BackendUtil.cpp?rev=269679&r1=269678&r2=269679&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/BackendUtil.cpp (original)
+++ cfe/trunk/lib/CodeGen/BackendUtil.cpp Mon May 16 13:54:58 2016
@@ -797,6 +797,20 @@ void clang::EmbedBitcode(llvm::Module *M
   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
   }
   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");
 }

Modified: cfe/trunk/test/Frontend/embed-bitcode.ll
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Frontend/embed-bitcode.ll?rev=269679&r1=269678&r2=269679&view=diff
==============================================================================
--- cfe/trunk/test/Frontend/embed-bitcode.ll (original)
+++ cfe/trunk/test/Frontend/embed-bitcode.ll Mon May 16 13:54:58 2016
@@ -31,10 +31,10 @@
 ; 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
@@ -42,10 +42,10 @@
 ; 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




More information about the cfe-commits mailing list