From: Steven Wu Date: Mon, 16 May 2016 18:54:58 +0000 (+0000) Subject: Change embed-bitcode linkage type X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=27bf4de988333b5027ed87ab65ab67b0cbd0dc02;p=clang 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 --- diff --git a/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp index bffa621a59..5a1db6c068 100644 --- a/lib/CodeGen/BackendUtil.cpp +++ b/lib/CodeGen/BackendUtil.cpp @@ -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 UsedArray; + SmallSet 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 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 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 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"); } diff --git a/test/Frontend/embed-bitcode.ll b/test/Frontend/embed-bitcode.ll index 0bd75f1ac0..bd2afb44bb 100644 --- a/test/Frontend/embed-bitcode.ll +++ b/test/Frontend/embed-bitcode.ll @@ -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