summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteven Wu <stevenwu@apple.com>2016-05-16 18:54:58 +0000
committerSteven Wu <stevenwu@apple.com>2016-05-16 18:54:58 +0000
commit2c059a55e26e12afe4576c40ce48be58b743e83b (patch)
treebf8a3e87a9f9424bb8fc44b99297bc6e8b761155
parent9b4ff336ce52b2c2d12a5e65bfc6341915da6ebc (diff)
downloadbcm5719-llvm-2c059a55e26e12afe4576c40ce48be58b743e83b.tar.gz
bcm5719-llvm-2c059a55e26e12afe4576c40ce48be58b743e83b.zip
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 llvm-svn: 269679
-rw-r--r--clang/lib/CodeGen/BackendUtil.cpp73
-rw-r--r--clang/test/Frontend/embed-bitcode.ll8
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
OpenPOWER on IntegriCloud