Skip to content

Commit bdd7138

Browse files
committed
Update embedded bitcode support to work with llvm r269706.
The original support for embedded bitcode used appending linkage for the magic internal variables that hold the bitcode and command line options, but that private linkage is a better fit. The only real reason for appending linkage was to prevent those variables from being optimized away. r269706 limits the use of appending linkage so that it cannot be used for those variables, so this switches to use private linkage and keep the variables alive with llvm.compiler.used. This is basically copied from clang r269679. rdar://problem/28685198. As of the swift-3.1-branch versions of Clang/LLVM, embedded bitcode is now working well enough that the tests can be reenabled. rdar://problem/26247134
1 parent 37cac6b commit bdd7138

File tree

4 files changed

+34
-9
lines changed

4 files changed

+34
-9
lines changed

lib/IRGen/IRGen.cpp

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,22 @@ static void embedBitcode(llvm::Module *M, const IRGenOptions &Opts)
517517
if (Opts.EmbedMode == IRGenEmbedMode::None)
518518
return;
519519

520+
// Save llvm.compiler.used and remove it.
521+
SmallVector<llvm::Constant*, 2> UsedArray;
522+
SmallSet<llvm::GlobalValue*, 4> UsedGlobals;
523+
auto *UsedElementType =
524+
llvm::Type::getInt8Ty(M->getContext())->getPointerTo(0);
525+
llvm::GlobalVariable *Used =
526+
collectUsedGlobalVariables(*M, UsedGlobals, true);
527+
for (auto *GV : UsedGlobals) {
528+
if (GV->getName() != "llvm.embedded.module" &&
529+
GV->getName() != "llvm.cmdline")
530+
UsedArray.push_back(
531+
ConstantExpr::getPointerBitCastOrAddrSpaceCast(GV, UsedElementType));
532+
}
533+
if (Used)
534+
Used->eraseFromParent();
535+
520536
// Embed the bitcode for the llvm module.
521537
std::string Data;
522538
llvm::raw_string_ostream OS(Data);
@@ -526,14 +542,15 @@ static void embedBitcode(llvm::Module *M, const IRGenOptions &Opts)
526542
ArrayRef<uint8_t> ModuleData((uint8_t*)OS.str().data(), OS.str().size());
527543
llvm::Constant *ModuleConstant =
528544
llvm::ConstantDataArray::get(M->getContext(), ModuleData);
529-
// Use Appending linkage so it doesn't get optimized out.
530545
llvm::GlobalVariable *GV = new llvm::GlobalVariable(*M,
531546
ModuleConstant->getType(), true,
532-
llvm::GlobalValue::AppendingLinkage,
547+
llvm::GlobalValue::PrivateLinkage,
533548
ModuleConstant);
549+
UsedArray.push_back(
550+
llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(GV, UsedElementType));
534551
GV->setSection("__LLVM,__bitcode");
535552
if (llvm::GlobalVariable *Old =
536-
M->getGlobalVariable("llvm.embedded.module")) {
553+
M->getGlobalVariable("llvm.embedded.module", true)) {
537554
GV->takeName(Old);
538555
Old->replaceAllUsesWith(GV);
539556
delete Old;
@@ -547,16 +564,28 @@ static void embedBitcode(llvm::Module *M, const IRGenOptions &Opts)
547564
llvm::Constant *CmdConstant =
548565
llvm::ConstantDataArray::get(M->getContext(), CmdData);
549566
GV = new llvm::GlobalVariable(*M, CmdConstant->getType(), true,
550-
llvm::GlobalValue::AppendingLinkage,
567+
llvm::GlobalValue::PrivateLinkage,
551568
CmdConstant);
552569
GV->setSection("__LLVM,__swift_cmdline");
553-
if (llvm::GlobalVariable *Old = M->getGlobalVariable("llvm.cmdline")) {
570+
UsedArray.push_back(
571+
llvm::ConstantExpr::getPointerBitCastOrAddrSpaceCast(GV, UsedElementType));
572+
if (llvm::GlobalVariable *Old = M->getGlobalVariable("llvm.cmdline", true)) {
554573
GV->takeName(Old);
555574
Old->replaceAllUsesWith(GV);
556575
delete Old;
557576
} else {
558577
GV->setName("llvm.cmdline");
559578
}
579+
580+
if (UsedArray.empty())
581+
return;
582+
583+
// Recreate llvm.compiler.used.
584+
auto *ATy = llvm::ArrayType::get(UsedElementType, UsedArray.size());
585+
auto *NewUsed = new GlobalVariable(
586+
*M, ATy, false, llvm::GlobalValue::AppendingLinkage,
587+
llvm::ConstantArray::get(ATy, UsedArray), "llvm.compiler.used");
588+
NewUsed->setSection("llvm.metadata");
560589
}
561590

562591
static void initLLVMModule(const IRGenModule &IGM) {

test/Driver/multi-threaded.swift

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
// REQUIRES: rdar23493035
2-
31
// RUN: rm -rf %t && mkdir -p %t
42
// RUN: %target-swiftc_driver -driver-print-jobs -module-name=ThisModule -wmo -num-threads 4 %S/Inputs/main.swift %s -emit-module -o test.swiftmodule | %FileCheck -check-prefix=MODULE %s
53
// RUN: echo "{\"%s\": {\"assembly\": \"/build/multi-threaded.s\"}, \"%S/Inputs/main.swift\": {\"assembly\": \"/build/main.s\"}}" > %t/ofms.json

test/Frontend/embed-bitcode.ll

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
; REQUIRES: CPU=x86_64
2-
; REQUIRES: rdar23493035
32
; RUN: llvm-as %s -o %t.bc
43
; RUN: %swift -target x86_64-apple-darwin10 -c -module-name someModule -embed-bitcode -disable-llvm-optzns -o %t2.o %t.bc -dump-clang-diagnostics 2> %t.diags.txt
54
; RUN: llvm-objdump -macho -section="__LLVM,__bitcode" %t2.o | %FileCheck %s

test/Frontend/embed-bitcode.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
// REQUIRES: CPU=x86_64
2-
// REQUIRES: rdar23493035
32
// RUN: %target-swift-frontend -c -module-name someModule -embed-bitcode-marker -o %t.o %s
43
// RUN: llvm-objdump -macho -section="__LLVM,__bitcode" %t.o | %FileCheck -check-prefix=MARKER %s
54
// RUN: llvm-objdump -macho -section="__LLVM,__swift_cmdline" %t.o | %FileCheck -check-prefix=MARKER-CMD %s

0 commit comments

Comments
 (0)