
Since ThinLTOBitcodeWriterPass handles many things for CFI and WPD, like updating vtable linkage, we need to prevent those changes from persisting in the non-LTO object code we will compile under FatLTO. The only non-invasive way to do that is to clone the module when serializing the module in ThinLTOBitcodeWriterPass. We may be able to avoid cloning in the future with additional infrastructure to restore the IR to its original state. Fixes #139440
50 lines
1.8 KiB
C++
50 lines
1.8 KiB
C++
//===- EmbedBitcodePass.cpp - Pass that embeds the bitcode into a global---===//
|
|
//
|
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
|
// See https://llvm.org/LICENSE.txt for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#include "llvm/Transforms/IPO/EmbedBitcodePass.h"
|
|
#include "llvm/Bitcode/BitcodeWriter.h"
|
|
#include "llvm/Bitcode/BitcodeWriterPass.h"
|
|
#include "llvm/IR/PassManager.h"
|
|
#include "llvm/Pass.h"
|
|
#include "llvm/Support/ErrorHandling.h"
|
|
#include "llvm/Support/MemoryBufferRef.h"
|
|
#include "llvm/Support/raw_ostream.h"
|
|
#include "llvm/TargetParser/Triple.h"
|
|
#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
|
|
#include "llvm/Transforms/Utils/Cloning.h"
|
|
#include "llvm/Transforms/Utils/ModuleUtils.h"
|
|
|
|
#include <string>
|
|
|
|
using namespace llvm;
|
|
|
|
PreservedAnalyses EmbedBitcodePass::run(Module &M, ModuleAnalysisManager &AM) {
|
|
if (M.getGlobalVariable("llvm.embedded.module", /*AllowInternal=*/true))
|
|
reportFatalUsageError("Can only embed the module once");
|
|
|
|
Triple T(M.getTargetTriple());
|
|
if (T.getObjectFormat() != Triple::ELF)
|
|
reportFatalUsageError(
|
|
"EmbedBitcode pass currently only supports ELF object format");
|
|
|
|
std::string Data;
|
|
raw_string_ostream OS(Data);
|
|
// Clone the module with Thin LTO, since ThinLTOBitcodeWriterPass changes
|
|
// vtable linkage that would break the non-lto object code for FatLTO.
|
|
if (IsThinLTO)
|
|
ThinLTOBitcodeWriterPass(OS, /*ThinLinkOS=*/nullptr)
|
|
.run(*llvm::CloneModule(M), AM);
|
|
else
|
|
BitcodeWriterPass(OS, /*ShouldPreserveUseListOrder=*/false, EmitLTOSummary)
|
|
.run(M, AM);
|
|
|
|
embedBufferInModule(M, MemoryBufferRef(Data, "ModuleData"), ".llvm.lto");
|
|
|
|
return PreservedAnalyses::all();
|
|
}
|