[clang] [llvm] Pass TargetMachine from from Clang to `BitcodeWriter`and `ThinLTOBitcodeWriter` pass for thin and fat LTO respectively. (PR #143692)
Garvit Gupta via llvm-commits
llvm-commits at lists.llvm.org
Wed Jun 11 11:03:13 PDT 2025
https://github.com/quic-garvgupt updated https://github.com/llvm/llvm-project/pull/143692
>From e4902f765b0ef58e015195f2b4974d1f44c6b0c1 Mon Sep 17 00:00:00 2001
From: Garvit Gupta <quic_garvgupt at quicinc.com>
Date: Mon, 26 May 2025 10:45:37 -0700
Subject: [PATCH] Pass TargetMachine from from Clang to `BitcodeWriter`and
`ThinLTOBitcodeWriter` pass for thin and fat LTO respectively.
Currently in the `initializeRecordStreamer` function in the
ModuleSymbolTable file, MCTargetOptions are initalized again even
though they get populated in BackendUtil.cpp. Because of this,
during lto, `IASSearchPaths` field of MCOptions which holds all
include paths gets override and thus compiler is not able to locate
files included using `.include` asm directive.
This patch fixes the above issue.
Fixes #112920
Change-Id: I099a940a46c3d8403207bc5f06fede2010163c34
---
clang/lib/CodeGen/BackendUtil.cpp | 4 +-
clang/test/CodeGen/Inputs/macros.s | 0
clang/test/CodeGen/RISCV/include.c | 11 +++
.../llvm/Analysis/ModuleSummaryAnalysis.h | 3 +-
llvm/include/llvm/Bitcode/BitcodeWriter.h | 14 ++-
llvm/include/llvm/Bitcode/BitcodeWriterPass.h | 11 ++-
llvm/include/llvm/Object/IRSymtab.h | 5 +-
llvm/include/llvm/Object/ModuleSymbolTable.h | 6 +-
.../Transforms/IPO/ThinLTOBitcodeWriter.h | 7 +-
llvm/lib/Analysis/ModuleSummaryAnalysis.cpp | 19 ++--
llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 21 +++--
llvm/lib/Bitcode/Writer/BitcodeWriterPass.cpp | 84 ++++++++++-------
llvm/lib/Object/IRSymtab.cpp | 11 ++-
llvm/lib/Object/ModuleSymbolTable.cpp | 93 +++++++++++--------
.../Transforms/IPO/ThinLTOBitcodeWriter.cpp | 35 +++++--
15 files changed, 205 insertions(+), 119 deletions(-)
create mode 100644 clang/test/CodeGen/Inputs/macros.s
create mode 100644 clang/test/CodeGen/RISCV/include.c
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index 88b3a4943e0d8..077175b2d4f93 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -1158,7 +1158,7 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
return;
}
MPM.addPass(ThinLTOBitcodeWriterPass(
- *OS, ThinLinkOS ? &ThinLinkOS->os() : nullptr));
+ *OS, ThinLinkOS ? &ThinLinkOS->os() : nullptr, false, TM.get()));
} else if (Action == Backend_EmitLL) {
MPM.addPass(PrintModulePass(*OS, "", CodeGenOpts.EmitLLVMUseLists,
/*EmitLTOSummary=*/true));
@@ -1176,7 +1176,7 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
}
if (Action == Backend_EmitBC) {
MPM.addPass(BitcodeWriterPass(*OS, CodeGenOpts.EmitLLVMUseLists,
- EmitLTOSummary));
+ EmitLTOSummary, false, TM.get()));
} else if (Action == Backend_EmitLL) {
MPM.addPass(PrintModulePass(*OS, "", CodeGenOpts.EmitLLVMUseLists,
EmitLTOSummary));
diff --git a/clang/test/CodeGen/Inputs/macros.s b/clang/test/CodeGen/Inputs/macros.s
new file mode 100644
index 0000000000000..e69de29bb2d1d
diff --git a/clang/test/CodeGen/RISCV/include.c b/clang/test/CodeGen/RISCV/include.c
new file mode 100644
index 0000000000000..89967cae3612c
--- /dev/null
+++ b/clang/test/CodeGen/RISCV/include.c
@@ -0,0 +1,11 @@
+// RUN: %clang --target=riscv32-unknown-elf -I %S/../Inputs/ -flto %s -c -o %t.full.bc
+// RUN: llvm-dis %t.full.bc -o - | FileCheck %s
+// RUN: %clang --target=riscv32-unknown-elf -I %S/../Inputs/ -flto=thin %s -c -o %t.thin.bc
+// RUN: llvm-dis %t.thin.bc -o - | FileCheck %s
+__asm__(".include \"macros.s\"");
+
+void test() {
+}
+
+// CHECK: module asm ".include \22macros.s\22"
+
diff --git a/llvm/include/llvm/Analysis/ModuleSummaryAnalysis.h b/llvm/include/llvm/Analysis/ModuleSummaryAnalysis.h
index 7e78e9b9f2262..4939f974d0c1d 100644
--- a/llvm/include/llvm/Analysis/ModuleSummaryAnalysis.h
+++ b/llvm/include/llvm/Analysis/ModuleSummaryAnalysis.h
@@ -27,6 +27,7 @@ class Function;
class Module;
class ProfileSummaryInfo;
class StackSafetyInfo;
+class TargetMachine;
/// Direct function to compute a \c ModuleSummaryIndex from a given module.
///
@@ -37,7 +38,7 @@ class StackSafetyInfo;
LLVM_ABI ModuleSummaryIndex buildModuleSummaryIndex(
const Module &M,
std::function<BlockFrequencyInfo *(const Function &F)> GetBFICallback,
- ProfileSummaryInfo *PSI,
+ ProfileSummaryInfo *PSI, const TargetMachine *TM = nullptr,
std::function<const StackSafetyInfo *(const Function &F)> GetSSICallback =
[](const Function &F) -> const StackSafetyInfo * { return nullptr; });
diff --git a/llvm/include/llvm/Bitcode/BitcodeWriter.h b/llvm/include/llvm/Bitcode/BitcodeWriter.h
index e9b573733451b..b8c1d57f4c43a 100644
--- a/llvm/include/llvm/Bitcode/BitcodeWriter.h
+++ b/llvm/include/llvm/Bitcode/BitcodeWriter.h
@@ -29,6 +29,7 @@ namespace llvm {
class BitstreamWriter;
class Module;
class raw_ostream;
+class TargetMachine;
class BitcodeWriter {
std::unique_ptr<BitstreamWriter> Stream;
@@ -45,10 +46,13 @@ class BitcodeWriter {
std::vector<Module *> Mods;
+ const TargetMachine *TM;
+
public:
/// Create a BitcodeWriter that writes to Buffer.
- LLVM_ABI BitcodeWriter(SmallVectorImpl<char> &Buffer);
- LLVM_ABI BitcodeWriter(raw_ostream &FS);
+ LLVM_ABI BitcodeWriter(SmallVectorImpl<char> &Buffer,
+ const TargetMachine *TM = nullptr);
+ LLVM_ABI BitcodeWriter(raw_ostream &FS, const TargetMachine *TM = nullptr);
LLVM_ABI ~BitcodeWriter();
@@ -135,7 +139,8 @@ LLVM_ABI void WriteBitcodeToFile(const Module &M, raw_ostream &Out,
bool ShouldPreserveUseListOrder = false,
const ModuleSummaryIndex *Index = nullptr,
bool GenerateHash = false,
- ModuleHash *ModHash = nullptr);
+ ModuleHash *ModHash = nullptr,
+ const TargetMachine *TM = nullptr);
/// Write the specified thin link bitcode file (i.e., the minimized bitcode
/// file) to the given raw output stream, where it will be written in a new
@@ -146,7 +151,8 @@ LLVM_ABI void WriteBitcodeToFile(const Module &M, raw_ostream &Out,
/// bitcode file writing.
LLVM_ABI void writeThinLinkBitcodeToFile(const Module &M, raw_ostream &Out,
const ModuleSummaryIndex &Index,
- const ModuleHash &ModHash);
+ const ModuleHash &ModHash,
+ const TargetMachine *TM = nullptr);
/// Write the specified module summary index to the given raw output stream,
/// where it will be written in a new bitcode block. This is used when
diff --git a/llvm/include/llvm/Bitcode/BitcodeWriterPass.h b/llvm/include/llvm/Bitcode/BitcodeWriterPass.h
index 3ce5db4ef1061..ae9fb763d4a64 100644
--- a/llvm/include/llvm/Bitcode/BitcodeWriterPass.h
+++ b/llvm/include/llvm/Bitcode/BitcodeWriterPass.h
@@ -22,6 +22,7 @@ class Module;
class ModulePass;
class Pass;
class raw_ostream;
+class TargetMachine;
/// Create and return a pass that writes the module to the specified
/// ostream. Note that this pass is designed for use with the legacy pass
@@ -31,7 +32,8 @@ class raw_ostream;
/// reproduced when deserialized.
LLVM_ABI ModulePass *
createBitcodeWriterPass(raw_ostream &Str,
- bool ShouldPreserveUseListOrder = false);
+ bool ShouldPreserveUseListOrder = false,
+ const TargetMachine *TM = nullptr);
/// Check whether a pass is a BitcodeWriterPass.
LLVM_ABI bool isBitcodeWriterPass(Pass *P);
@@ -45,6 +47,7 @@ class BitcodeWriterPass : public PassInfoMixin<BitcodeWriterPass> {
bool ShouldPreserveUseListOrder;
bool EmitSummaryIndex;
bool EmitModuleHash;
+ const TargetMachine *TM;
public:
/// Construct a bitcode writer pass around a particular output stream.
@@ -57,9 +60,11 @@ class BitcodeWriterPass : public PassInfoMixin<BitcodeWriterPass> {
explicit BitcodeWriterPass(raw_ostream &OS,
bool ShouldPreserveUseListOrder = false,
bool EmitSummaryIndex = false,
- bool EmitModuleHash = false)
+ bool EmitModuleHash = false,
+ const TargetMachine *TM = nullptr)
: OS(OS), ShouldPreserveUseListOrder(ShouldPreserveUseListOrder),
- EmitSummaryIndex(EmitSummaryIndex), EmitModuleHash(EmitModuleHash) {}
+ EmitSummaryIndex(EmitSummaryIndex), EmitModuleHash(EmitModuleHash),
+ TM(TM) {}
/// Run the bitcode writer pass, and output the module to the selected
/// output stream.
diff --git a/llvm/include/llvm/Object/IRSymtab.h b/llvm/include/llvm/Object/IRSymtab.h
index 0b7d6e0734e82..582945985841c 100644
--- a/llvm/include/llvm/Object/IRSymtab.h
+++ b/llvm/include/llvm/Object/IRSymtab.h
@@ -41,6 +41,7 @@ namespace llvm {
struct BitcodeFileContents;
class StringTableBuilder;
+class TargetMachine;
namespace irsymtab {
@@ -164,8 +165,8 @@ struct Header {
/// Fills in Symtab and StrtabBuilder with a valid symbol and string table for
/// Mods.
LLVM_ABI Error build(ArrayRef<Module *> Mods, SmallVector<char, 0> &Symtab,
- StringTableBuilder &StrtabBuilder,
- BumpPtrAllocator &Alloc);
+ StringTableBuilder &StrtabBuilder, BumpPtrAllocator &Alloc,
+ const TargetMachine *TM = nullptr);
/// This represents a symbol that has been read from a storage::Symbol and
/// possibly a storage::Uncommon.
diff --git a/llvm/include/llvm/Object/ModuleSymbolTable.h b/llvm/include/llvm/Object/ModuleSymbolTable.h
index 564ce76b3feb1..274f20ac225bf 100644
--- a/llvm/include/llvm/Object/ModuleSymbolTable.h
+++ b/llvm/include/llvm/Object/ModuleSymbolTable.h
@@ -30,6 +30,7 @@ namespace llvm {
class GlobalValue;
class Module;
+class TargetMachine;
class ModuleSymbolTable {
public:
@@ -45,7 +46,7 @@ class ModuleSymbolTable {
public:
ArrayRef<Symbol> symbols() const { return SymTab; }
- LLVM_ABI void addModule(Module *M);
+ LLVM_ABI void addModule(Module *M, const TargetMachine *TM = nullptr);
LLVM_ABI void printSymbolName(raw_ostream &OS, Symbol S) const;
LLVM_ABI uint32_t getSymbolFlags(Symbol S) const;
@@ -57,7 +58,8 @@ class ModuleSymbolTable {
/// and the associated flags.
LLVM_ABI static void CollectAsmSymbols(
const Module &M,
- function_ref<void(StringRef, object::BasicSymbolRef::Flags)> AsmSymbol);
+ function_ref<void(StringRef, object::BasicSymbolRef::Flags)> AsmSymbol,
+ const TargetMachine *TM = nullptr);
/// Parse inline ASM and collect the symvers directives that are defined in
/// the current module.
diff --git a/llvm/include/llvm/Transforms/IPO/ThinLTOBitcodeWriter.h b/llvm/include/llvm/Transforms/IPO/ThinLTOBitcodeWriter.h
index a21db26f1edbc..4a169b9cd0b9a 100644
--- a/llvm/include/llvm/Transforms/IPO/ThinLTOBitcodeWriter.h
+++ b/llvm/include/llvm/Transforms/IPO/ThinLTOBitcodeWriter.h
@@ -22,20 +22,23 @@
namespace llvm {
class Module;
class raw_ostream;
+class TargetMachine;
class ThinLTOBitcodeWriterPass
: public PassInfoMixin<ThinLTOBitcodeWriterPass> {
raw_ostream &OS;
raw_ostream *ThinLinkOS;
const bool ShouldPreserveUseListOrder;
+ const TargetMachine *TM;
public:
// Writes bitcode to OS. Also write thin link file to ThinLinkOS, if
// it's not nullptr.
ThinLTOBitcodeWriterPass(raw_ostream &OS, raw_ostream *ThinLinkOS,
- bool ShouldPreserveUseListOrder = false)
+ bool ShouldPreserveUseListOrder = false,
+ const TargetMachine *TM = nullptr)
: OS(OS), ThinLinkOS(ThinLinkOS),
- ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {}
+ ShouldPreserveUseListOrder(ShouldPreserveUseListOrder), TM(TM) {}
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM);
diff --git a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
index a317ac471a231..5b678132d0784 100644
--- a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
+++ b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
@@ -934,7 +934,7 @@ static void setLiveRoot(ModuleSummaryIndex &Index, StringRef Name) {
ModuleSummaryIndex llvm::buildModuleSummaryIndex(
const Module &M,
std::function<BlockFrequencyInfo *(const Function &F)> GetBFICallback,
- ProfileSummaryInfo *PSI,
+ ProfileSummaryInfo *PSI, const TargetMachine *TM,
std::function<const StackSafetyInfo *(const Function &F)> GetSSICallback) {
assert(PSI);
bool EnableSplitLTOUnit = false;
@@ -978,7 +978,8 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex(
// be listed on the llvm.used or llvm.compiler.used global and marked as
// referenced from there.
ModuleSymbolTable::CollectAsmSymbols(
- M, [&](StringRef Name, object::BasicSymbolRef::Flags Flags) {
+ M,
+ [&](StringRef Name, object::BasicSymbolRef::Flags Flags) {
// Symbols not marked as Weak or Global are local definitions.
if (Flags & (object::BasicSymbolRef::SF_Weak |
object::BasicSymbolRef::SF_Global))
@@ -987,7 +988,8 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex(
GlobalValue *GV = M.getNamedValue(Name);
if (!GV)
return;
- assert(GV->isDeclaration() && "Def in module asm already has definition");
+ assert(GV->isDeclaration() &&
+ "Def in module asm already has definition");
GlobalValueSummary::GVFlags GVFlags(
GlobalValue::InternalLinkage, GlobalValue::DefaultVisibility,
/* NotEligibleToImport = */ true,
@@ -1031,7 +1033,8 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex(
SmallVector<ValueInfo, 0>{});
Index.addGlobalValueSummary(*GV, std::move(Summary));
}
- });
+ },
+ TM);
}
bool IsThinLTO = true;
@@ -1144,8 +1147,8 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex(
AnalysisKey ModuleSummaryIndexAnalysis::Key;
-ModuleSummaryIndex
-ModuleSummaryIndexAnalysis::run(Module &M, ModuleAnalysisManager &AM) {
+ModuleSummaryIndex ModuleSummaryIndexAnalysis::run(Module &M,
+ ModuleAnalysisManager &AM) {
ProfileSummaryInfo &PSI = AM.getResult<ProfileSummaryAnalysis>(M);
auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
bool NeedSSI = needsParamAccessSummary(M);
@@ -1155,7 +1158,7 @@ ModuleSummaryIndexAnalysis::run(Module &M, ModuleAnalysisManager &AM) {
return &FAM.getResult<BlockFrequencyAnalysis>(
*const_cast<Function *>(&F));
},
- &PSI,
+ &PSI, nullptr,
[&FAM, NeedSSI](const Function &F) -> const StackSafetyInfo * {
return NeedSSI ? &FAM.getResult<StackSafetyAnalysis>(
const_cast<Function &>(F))
@@ -1190,7 +1193,7 @@ bool ModuleSummaryIndexWrapperPass::runOnModule(Module &M) {
*const_cast<Function *>(&F))
.getBFI());
},
- PSI,
+ PSI, nullptr,
[&](const Function &F) -> const StackSafetyInfo * {
return NeedSSI ? &getAnalysis<StackSafetyInfoWrapperPass>(
const_cast<Function &>(F))
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
index 628b939af19ce..c6ce2dd69076f 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -5357,13 +5357,14 @@ static void writeBitcodeHeader(BitstreamWriter &Stream) {
Stream.Emit(0xD, 4);
}
-BitcodeWriter::BitcodeWriter(SmallVectorImpl<char> &Buffer)
- : Stream(new BitstreamWriter(Buffer)) {
+BitcodeWriter::BitcodeWriter(SmallVectorImpl<char> &Buffer,
+ const TargetMachine *TM)
+ : Stream(new BitstreamWriter(Buffer)), TM(TM) {
writeBitcodeHeader(*Stream);
}
-BitcodeWriter::BitcodeWriter(raw_ostream &FS)
- : Stream(new BitstreamWriter(FS, FlushThreshold)) {
+BitcodeWriter::BitcodeWriter(raw_ostream &FS, const TargetMachine *TM)
+ : Stream(new BitstreamWriter(FS, FlushThreshold)), TM(TM) {
writeBitcodeHeader(*Stream);
}
@@ -5405,7 +5406,7 @@ void BitcodeWriter::writeSymtab() {
// module is malformed (e.g. it contains an invalid alias). Writing a symbol
// table is not required for correctness, but we still want to be able to
// write malformed modules to bitcode files, so swallow the error.
- if (Error E = irsymtab::build(Mods, Symtab, StrtabBuilder, Alloc)) {
+ if (Error E = irsymtab::build(Mods, Symtab, StrtabBuilder, Alloc, TM)) {
consumeError(std::move(E));
return;
}
@@ -5465,7 +5466,8 @@ void BitcodeWriter::writeIndex(
void llvm::WriteBitcodeToFile(const Module &M, raw_ostream &Out,
bool ShouldPreserveUseListOrder,
const ModuleSummaryIndex *Index,
- bool GenerateHash, ModuleHash *ModHash) {
+ bool GenerateHash, ModuleHash *ModHash,
+ const TargetMachine *TM) {
auto Write = [&](BitcodeWriter &Writer) {
Writer.writeModule(M, ShouldPreserveUseListOrder, Index, GenerateHash,
ModHash);
@@ -5486,7 +5488,7 @@ void llvm::WriteBitcodeToFile(const Module &M, raw_ostream &Out,
emitDarwinBCHeaderAndTrailer(Buffer, TT);
Out.write(Buffer.data(), Buffer.size());
} else {
- BitcodeWriter Writer(Out);
+ BitcodeWriter Writer(Out, TM);
Write(Writer);
}
}
@@ -5672,11 +5674,12 @@ void BitcodeWriter::writeThinLinkBitcode(const Module &M,
// writing the per-module index file for ThinLTO.
void llvm::writeThinLinkBitcodeToFile(const Module &M, raw_ostream &Out,
const ModuleSummaryIndex &Index,
- const ModuleHash &ModHash) {
+ const ModuleHash &ModHash,
+ const TargetMachine *TM) {
SmallVector<char, 0> Buffer;
Buffer.reserve(256 * 1024);
- BitcodeWriter Writer(Buffer);
+ BitcodeWriter Writer(Buffer, TM);
Writer.writeThinLinkBitcode(M, Index, ModHash);
Writer.writeSymtab();
Writer.writeStrtab();
diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriterPass.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriterPass.cpp
index e48f735ded831..2a5c20976b497 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriterPass.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriterPass.cpp
@@ -11,7 +11,10 @@
//===----------------------------------------------------------------------===//
#include "llvm/Bitcode/BitcodeWriterPass.h"
+#include "llvm/Analysis/BlockFrequencyInfo.h"
#include "llvm/Analysis/ModuleSummaryAnalysis.h"
+#include "llvm/Analysis/ProfileSummaryInfo.h"
+#include "llvm/Analysis/StackSafetyAnalysis.h"
#include "llvm/Bitcode/BitcodeWriter.h"
#include "llvm/IR/PassManager.h"
#include "llvm/InitializePasses.h"
@@ -21,46 +24,64 @@ using namespace llvm;
PreservedAnalyses BitcodeWriterPass::run(Module &M, ModuleAnalysisManager &AM) {
M.removeDebugIntrinsicDeclarations();
- const ModuleSummaryIndex *Index =
- EmitSummaryIndex ? &(AM.getResult<ModuleSummaryIndexAnalysis>(M))
- : nullptr;
- WriteBitcodeToFile(M, OS, ShouldPreserveUseListOrder, Index, EmitModuleHash);
+ ProfileSummaryInfo &PSI = AM.getResult<ProfileSummaryAnalysis>(M);
+ auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
+ bool NeedSSI = needsParamAccessSummary(M);
+ std::unique_ptr<ModuleSummaryIndex> NewIndex = nullptr;
+ if (EmitSummaryIndex) {
+ NewIndex = std::make_unique<ModuleSummaryIndex>(buildModuleSummaryIndex(
+ M,
+ [&FAM](const Function &F) {
+ return &FAM.getResult<BlockFrequencyAnalysis>(
+ *const_cast<Function *>(&F));
+ },
+ &PSI, TM,
+ [&FAM, NeedSSI](const Function &F) -> const StackSafetyInfo * {
+ return NeedSSI ? &FAM.getResult<StackSafetyAnalysis>(
+ const_cast<Function &>(F))
+ : nullptr;
+ }));
+ }
+ WriteBitcodeToFile(M, OS, ShouldPreserveUseListOrder, NewIndex.get(),
+ EmitModuleHash, /*ModHash=*/nullptr, TM);
return PreservedAnalyses::all();
}
namespace {
- class WriteBitcodePass : public ModulePass {
- raw_ostream &OS; // raw_ostream to print on
- bool ShouldPreserveUseListOrder;
+class WriteBitcodePass : public ModulePass {
+ raw_ostream &OS; // raw_ostream to print on
+ bool ShouldPreserveUseListOrder;
+ const TargetMachine *TM;
- public:
- static char ID; // Pass identification, replacement for typeid
- WriteBitcodePass() : ModulePass(ID), OS(dbgs()) {
- initializeWriteBitcodePassPass(*PassRegistry::getPassRegistry());
- }
+public:
+ static char ID; // Pass identification, replacement for typeid
+ WriteBitcodePass() : ModulePass(ID), OS(dbgs()) {
+ initializeWriteBitcodePassPass(*PassRegistry::getPassRegistry());
+ }
- explicit WriteBitcodePass(raw_ostream &o, bool ShouldPreserveUseListOrder)
- : ModulePass(ID), OS(o),
- ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {
- initializeWriteBitcodePassPass(*PassRegistry::getPassRegistry());
- }
+ explicit WriteBitcodePass(raw_ostream &O, bool ShouldPreserveUseListOrder,
+ const TargetMachine *TM = nullptr)
+ : ModulePass(ID), OS(O),
+ ShouldPreserveUseListOrder(ShouldPreserveUseListOrder), TM(TM) {
+ initializeWriteBitcodePassPass(*PassRegistry::getPassRegistry());
+ }
- StringRef getPassName() const override { return "Bitcode Writer"; }
+ StringRef getPassName() const override { return "Bitcode Writer"; }
- bool runOnModule(Module &M) override {
- M.removeDebugIntrinsicDeclarations();
+ bool runOnModule(Module &M) override {
+ M.removeDebugIntrinsicDeclarations();
- WriteBitcodeToFile(M, OS, ShouldPreserveUseListOrder, /*Index=*/nullptr,
- /*EmitModuleHash=*/false);
+ WriteBitcodeToFile(M, OS, ShouldPreserveUseListOrder, /*Index=*/nullptr,
+ /*GenerateHash=*/false, /*ModHash=*/nullptr, TM);
- return false;
- }
- void getAnalysisUsage(AnalysisUsage &AU) const override {
- AU.setPreservesAll();
- }
- };
-}
+ return false;
+ }
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.setPreservesAll();
+ }
+};
+} // namespace
char WriteBitcodePass::ID = 0;
INITIALIZE_PASS_BEGIN(WriteBitcodePass, "write-bitcode", "Write Bitcode", false,
@@ -70,8 +91,9 @@ INITIALIZE_PASS_END(WriteBitcodePass, "write-bitcode", "Write Bitcode", false,
true)
ModulePass *llvm::createBitcodeWriterPass(raw_ostream &Str,
- bool ShouldPreserveUseListOrder) {
- return new WriteBitcodePass(Str, ShouldPreserveUseListOrder);
+ bool ShouldPreserveUseListOrder,
+ const TargetMachine *TM) {
+ return new WriteBitcodePass(Str, ShouldPreserveUseListOrder, TM);
}
bool llvm::isBitcodeWriterPass(Pass *P) {
diff --git a/llvm/lib/Object/IRSymtab.cpp b/llvm/lib/Object/IRSymtab.cpp
index 806477ae3de01..8071af0b9f7ae 100644
--- a/llvm/lib/Object/IRSymtab.cpp
+++ b/llvm/lib/Object/IRSymtab.cpp
@@ -76,13 +76,14 @@ struct Builder {
SmallVector<char, 0> &Symtab;
StringTableBuilder &StrtabBuilder;
StringSaver Saver;
+ const TargetMachine *TM;
// This ctor initializes a StringSaver using the passed in BumpPtrAllocator.
// The StringTableBuilder does not create a copy of any strings added to it,
// so this provides somewhere to store any strings that we create.
Builder(SmallVector<char, 0> &Symtab, StringTableBuilder &StrtabBuilder,
- BumpPtrAllocator &Alloc)
- : Symtab(Symtab), StrtabBuilder(StrtabBuilder), Saver(Alloc) {}
+ BumpPtrAllocator &Alloc, const TargetMachine *TM)
+ : Symtab(Symtab), StrtabBuilder(StrtabBuilder), Saver(Alloc), TM(TM) {}
DenseMap<const Comdat *, int> ComdatMap;
Mangler Mang;
@@ -143,7 +144,7 @@ Error Builder::addModule(Module *M) {
SmallPtrSet<GlobalValue *, 4> Used(llvm::from_range, UsedV);
ModuleSymbolTable Msymtab;
- Msymtab.addModule(M);
+ Msymtab.addModule(M, TM);
storage::Module Mod;
Mod.Begin = Syms.size();
@@ -376,8 +377,8 @@ Error Builder::build(ArrayRef<Module *> IRMods) {
Error irsymtab::build(ArrayRef<Module *> Mods, SmallVector<char, 0> &Symtab,
StringTableBuilder &StrtabBuilder,
- BumpPtrAllocator &Alloc) {
- return Builder(Symtab, StrtabBuilder, Alloc).build(Mods);
+ BumpPtrAllocator &Alloc, const TargetMachine *TM) {
+ return Builder(Symtab, StrtabBuilder, Alloc, TM).build(Mods);
}
// Upgrade a vector of bitcode modules created by an old version of LLVM by
diff --git a/llvm/lib/Object/ModuleSymbolTable.cpp b/llvm/lib/Object/ModuleSymbolTable.cpp
index 1706772912772..b151b93601f80 100644
--- a/llvm/lib/Object/ModuleSymbolTable.cpp
+++ b/llvm/lib/Object/ModuleSymbolTable.cpp
@@ -40,6 +40,7 @@
#include "llvm/Support/SMLoc.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/raw_ostream.h"
+#include "llvm/Target/TargetMachine.h"
#include "llvm/TargetParser/Triple.h"
#include <cassert>
#include <cstdint>
@@ -49,7 +50,7 @@
using namespace llvm;
using namespace object;
-void ModuleSymbolTable::addModule(Module *M) {
+void ModuleSymbolTable::addModule(Module *M, const TargetMachine *TM) {
if (FirstMod)
assert(FirstMod->getTargetTriple() == M->getTargetTriple());
else
@@ -58,15 +59,18 @@ void ModuleSymbolTable::addModule(Module *M) {
for (GlobalValue &GV : M->global_values())
SymTab.push_back(&GV);
- CollectAsmSymbols(*M, [this](StringRef Name, BasicSymbolRef::Flags Flags) {
- SymTab.push_back(new (AsmSymbols.Allocate())
- AsmSymbol(std::string(Name), Flags));
- });
+ CollectAsmSymbols(
+ *M,
+ [this](StringRef Name, BasicSymbolRef::Flags Flags) {
+ SymTab.push_back(new (AsmSymbols.Allocate())
+ AsmSymbol(std::string(Name), Flags));
+ },
+ TM);
}
-static void
-initializeRecordStreamer(const Module &M,
- function_ref<void(RecordStreamer &)> Init) {
+static void initializeRecordStreamer(const Module &M,
+ function_ref<void(RecordStreamer &)> Init,
+ const TargetMachine *TM = nullptr) {
// This function may be called twice, once for ModuleSummaryIndexAnalysis and
// the other when writing the IR symbol table. If parsing inline assembly has
// caused errors in the first run, suppress the second run.
@@ -89,6 +93,8 @@ initializeRecordStreamer(const Module &M,
std::unique_ptr<MCAsmInfo> MAI(T->createMCAsmInfo(*MRI, TT.str(), MCOptions));
if (!MAI)
return;
+ if (TM)
+ MCOptions = TM->Options.MCOptions;
std::unique_ptr<MCSubtargetInfo> STI(
T->createMCSubtargetInfo(TT.str(), "", ""));
@@ -104,6 +110,7 @@ initializeRecordStreamer(const Module &M,
SourceMgr SrcMgr;
SrcMgr.AddNewSourceBuffer(std::move(Buffer), SMLoc());
+ SrcMgr.setIncludeDirs(MCOptions.IASSearchPaths);
MCContext MCCtx(TT, MAI.get(), MRI.get(), STI.get(), &SrcMgr);
std::unique_ptr<MCObjectFileInfo> MOFI(
T->createMCObjectFileInfo(MCCtx, /*PIC=*/false));
@@ -139,39 +146,43 @@ initializeRecordStreamer(const Module &M,
void ModuleSymbolTable::CollectAsmSymbols(
const Module &M,
- function_ref<void(StringRef, BasicSymbolRef::Flags)> AsmSymbol) {
- initializeRecordStreamer(M, [&](RecordStreamer &Streamer) {
- Streamer.flushSymverDirectives();
-
- for (auto &KV : Streamer) {
- StringRef Key = KV.first();
- RecordStreamer::State Value = KV.second;
- // FIXME: For now we just assume that all asm symbols are executable.
- uint32_t Res = BasicSymbolRef::SF_Executable;
- switch (Value) {
- case RecordStreamer::NeverSeen:
- llvm_unreachable("NeverSeen should have been replaced earlier");
- case RecordStreamer::DefinedGlobal:
- Res |= BasicSymbolRef::SF_Global;
- break;
- case RecordStreamer::Defined:
- break;
- case RecordStreamer::Global:
- case RecordStreamer::Used:
- Res |= BasicSymbolRef::SF_Undefined;
- Res |= BasicSymbolRef::SF_Global;
- break;
- case RecordStreamer::DefinedWeak:
- Res |= BasicSymbolRef::SF_Weak;
- Res |= BasicSymbolRef::SF_Global;
- break;
- case RecordStreamer::UndefinedWeak:
- Res |= BasicSymbolRef::SF_Weak;
- Res |= BasicSymbolRef::SF_Undefined;
- }
- AsmSymbol(Key, BasicSymbolRef::Flags(Res));
- }
- });
+ function_ref<void(StringRef, BasicSymbolRef::Flags)> AsmSymbol,
+ const TargetMachine *TM) {
+ initializeRecordStreamer(
+ M,
+ [&](RecordStreamer &Streamer) {
+ Streamer.flushSymverDirectives();
+
+ for (auto &KV : Streamer) {
+ StringRef Key = KV.first();
+ RecordStreamer::State Value = KV.second;
+ // FIXME: For now we just assume that all asm symbols are executable.
+ uint32_t Res = BasicSymbolRef::SF_Executable;
+ switch (Value) {
+ case RecordStreamer::NeverSeen:
+ llvm_unreachable("NeverSeen should have been replaced earlier");
+ case RecordStreamer::DefinedGlobal:
+ Res |= BasicSymbolRef::SF_Global;
+ break;
+ case RecordStreamer::Defined:
+ break;
+ case RecordStreamer::Global:
+ case RecordStreamer::Used:
+ Res |= BasicSymbolRef::SF_Undefined;
+ Res |= BasicSymbolRef::SF_Global;
+ break;
+ case RecordStreamer::DefinedWeak:
+ Res |= BasicSymbolRef::SF_Weak;
+ Res |= BasicSymbolRef::SF_Global;
+ break;
+ case RecordStreamer::UndefinedWeak:
+ Res |= BasicSymbolRef::SF_Weak;
+ Res |= BasicSymbolRef::SF_Undefined;
+ }
+ AsmSymbol(Key, BasicSymbolRef::Flags(Res));
+ }
+ },
+ TM);
// In ELF, object code generated for x86-32 and some code models of x86-64 may
// reference the special symbol _GLOBAL_OFFSET_TABLE_ that is not used in the
diff --git a/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp b/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
index e276376f21583..38a6868219957 100644
--- a/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
+++ b/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
@@ -8,10 +8,13 @@
#include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
#include "llvm/Analysis/BasicAliasAnalysis.h"
+#include "llvm/Analysis/BlockFrequencyInfo.h"
#include "llvm/Analysis/ModuleSummaryAnalysis.h"
#include "llvm/Analysis/ProfileSummaryInfo.h"
+#include "llvm/Analysis/StackSafetyAnalysis.h"
#include "llvm/Analysis/TypeMetadataUtils.h"
#include "llvm/Bitcode/BitcodeWriter.h"
+#include "llvm/Bitcode/BitcodeWriterPass.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/Instructions.h"
@@ -532,7 +535,8 @@ bool hasTypeMetadata(Module &M) {
bool writeThinLTOBitcode(raw_ostream &OS, raw_ostream *ThinLinkOS,
function_ref<AAResults &(Function &)> AARGetter,
Module &M, const ModuleSummaryIndex *Index,
- const bool ShouldPreserveUseListOrder) {
+ const bool ShouldPreserveUseListOrder,
+ const TargetMachine *TM = nullptr) {
std::unique_ptr<ModuleSummaryIndex> NewIndex = nullptr;
// See if this module has any type metadata. If so, we try to split it
// or at least promote type ids to enable WPD.
@@ -556,7 +560,7 @@ bool writeThinLTOBitcode(raw_ostream &OS, raw_ostream *ThinLinkOS,
// buildModuleSummaryIndex when Module(s) are ready.
ProfileSummaryInfo PSI(M);
NewIndex = std::make_unique<ModuleSummaryIndex>(
- buildModuleSummaryIndex(M, nullptr, &PSI));
+ buildModuleSummaryIndex(M, nullptr, &PSI, TM));
Index = NewIndex.get();
}
}
@@ -568,12 +572,12 @@ bool writeThinLTOBitcode(raw_ostream &OS, raw_ostream *ThinLinkOS,
// produced for the full link.
ModuleHash ModHash = {{0}};
WriteBitcodeToFile(M, OS, ShouldPreserveUseListOrder, Index,
- /*GenerateHash=*/true, &ModHash);
+ /*GenerateHash=*/true, &ModHash, TM);
// If a minimized bitcode module was requested for the thin link, only
// the information that is needed by thin link will be written in the
// given OS.
if (ThinLinkOS && Index)
- writeThinLinkBitcodeToFile(M, *ThinLinkOS, *Index, ModHash);
+ writeThinLinkBitcodeToFile(M, *ThinLinkOS, *Index, ModHash, TM);
return false;
}
@@ -581,18 +585,31 @@ bool writeThinLTOBitcode(raw_ostream &OS, raw_ostream *ThinLinkOS,
PreservedAnalyses
llvm::ThinLTOBitcodeWriterPass::run(Module &M, ModuleAnalysisManager &AM) {
- FunctionAnalysisManager &FAM =
- AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
-
M.removeDebugIntrinsicDeclarations();
+ FunctionAnalysisManager &FAM =
+ AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
+ ProfileSummaryInfo &PSI = AM.getResult<ProfileSummaryAnalysis>(M);
+ bool NeedSSI = needsParamAccessSummary(M);
+ std::unique_ptr<ModuleSummaryIndex> NewIndex = nullptr;
+ NewIndex = std::make_unique<ModuleSummaryIndex>(buildModuleSummaryIndex(
+ M,
+ [&FAM](const Function &F) {
+ return &FAM.getResult<BlockFrequencyAnalysis>(
+ *const_cast<Function *>(&F));
+ },
+ &PSI, TM,
+ [&FAM, NeedSSI](const Function &F) -> const StackSafetyInfo * {
+ return NeedSSI ? &FAM.getResult<StackSafetyAnalysis>(
+ const_cast<Function &>(F))
+ : nullptr;
+ }));
bool Changed = writeThinLTOBitcode(
OS, ThinLinkOS,
[&FAM](Function &F) -> AAResults & {
return FAM.getResult<AAManager>(F);
},
- M, &AM.getResult<ModuleSummaryIndexAnalysis>(M),
- ShouldPreserveUseListOrder);
+ M, NewIndex.get(), ShouldPreserveUseListOrder, TM);
return Changed ? PreservedAnalyses::none() : PreservedAnalyses::all();
}
More information about the llvm-commits
mailing list