diff options
-rw-r--r-- | clang/lib/CodeGen/BackendUtil.cpp | 73 | ||||
-rw-r--r-- | clang/test/Frontend/embed-bitcode.ll | 8 |
2 files changed, 55 insertions, 26 deletions
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp index bffa621a596..5a1db6c0681 100644 --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/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<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"); } diff --git a/clang/test/Frontend/embed-bitcode.ll b/clang/test/Frontend/embed-bitcode.ll index 0bd75f1ac0d..bd2afb44bb0 100644 --- a/clang/test/Frontend/embed-bitcode.ll +++ b/clang/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 |