[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
Sun Aug 3 11:25:38 PDT 2025
https://github.com/quic-garvgupt updated https://github.com/llvm/llvm-project/pull/143692
>From 2ce59cc209f7ffc449f20773e76414839a5125b6 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 | 5 +-
clang/test/CodeGen/Inputs/macros.s | 0
clang/test/CodeGen/RISCV/include.c | 11 +++
.../llvm/Analysis/ModuleSummaryAnalysis.h | 6 +-
llvm/include/llvm/Bitcode/BitcodeWriter.h | 14 ++-
llvm/include/llvm/Bitcode/BitcodeWriterPass.h | 14 ++-
llvm/include/llvm/IR/PassManager.h | 8 ++
llvm/include/llvm/Object/IRSymtab.h | 5 +-
llvm/include/llvm/Object/ModuleSymbolTable.h | 6 +-
.../llvm/Transforms/IPO/EmbedBitcodePass.h | 3 +-
.../Transforms/IPO/ThinLTOBitcodeWriter.h | 10 +-
llvm/lib/Analysis/ModuleSummaryAnalysis.cpp | 25 +++--
llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 21 +++--
llvm/lib/Bitcode/Writer/BitcodeWriterPass.cpp | 25 +++--
llvm/lib/Object/IRSymtab.cpp | 11 ++-
llvm/lib/Object/ModuleSymbolTable.cpp | 94 +++++++++++--------
llvm/lib/Transforms/IPO/EmbedBitcodePass.cpp | 3 +-
.../Transforms/IPO/ThinLTOBitcodeWriter.cpp | 20 ++--
18 files changed, 178 insertions(+), 103 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 1c92ea45c7458..01fa8572aee24 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -1155,7 +1155,8 @@ void EmitAssemblyHelper::RunOptimizationPipeline(
return;
}
MPM.addPass(ThinLTOBitcodeWriterPass(
- *OS, ThinLinkOS ? &ThinLinkOS->os() : nullptr));
+ *OS, ThinLinkOS ? &ThinLinkOS->os() : nullptr,
+ /* ShouldPreserveUseListOrder */ false, TM.get()));
} else if (Action == Backend_EmitLL) {
MPM.addPass(PrintModulePass(*OS, "", CodeGenOpts.EmitLLVMUseLists,
/*EmitLTOSummary=*/true));
@@ -1173,7 +1174,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..e99d9ebabfff6 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; });
@@ -51,7 +52,8 @@ class ModuleSummaryIndexAnalysis
public:
using Result = ModuleSummaryIndex;
- LLVM_ABI Result run(Module &M, ModuleAnalysisManager &AM);
+ LLVM_ABI Result run(Module &M, ModuleSummaryIndexAnalysisManager &AM,
+ const TargetMachine *TM = nullptr);
};
/// Legacy wrapper pass to provide the ModuleSummaryIndex object.
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..d786c9f5fca21 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,13 +60,16 @@ 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.
- LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
+ LLVM_ABI PreservedAnalyses run(Module &M,
+ ModuleSummaryIndexAnalysisManager &AM);
static bool isRequired() { return true; }
};
diff --git a/llvm/include/llvm/IR/PassManager.h b/llvm/include/llvm/IR/PassManager.h
index 4f44ae56eb3c7..2f6fe38667f0d 100644
--- a/llvm/include/llvm/IR/PassManager.h
+++ b/llvm/include/llvm/IR/PassManager.h
@@ -59,6 +59,7 @@ namespace llvm {
class Function;
class Module;
+class TargetMachine;
// Forward declare the analysis manager template.
template <typename IRUnitT, typename... ExtraArgTs> class AnalysisManager;
@@ -542,6 +543,13 @@ extern template class LLVM_TEMPLATE_ABI AnalysisManager<Module>;
/// Convenience typedef for the Module analysis manager.
using ModuleAnalysisManager = AnalysisManager<Module>;
+extern template class LLVM_TEMPLATE_ABI
+ AnalysisManager<Module, const TargetMachine *>;
+
+/// Separate typedef for ModuleSummaryAnalysisPass to pass TargetMachine to it.
+using ModuleSummaryIndexAnalysisManager =
+ AnalysisManager<Module, const TargetMachine *>;
+
extern template class LLVM_TEMPLATE_ABI AnalysisManager<Function>;
/// Convenience typedef for the Function analysis manager.
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/EmbedBitcodePass.h b/llvm/include/llvm/Transforms/IPO/EmbedBitcodePass.h
index dcd6d5f446c03..53a7867fc1ff0 100644
--- a/llvm/include/llvm/Transforms/IPO/EmbedBitcodePass.h
+++ b/llvm/include/llvm/Transforms/IPO/EmbedBitcodePass.h
@@ -45,7 +45,8 @@ class EmbedBitcodePass : public PassInfoMixin<EmbedBitcodePass> {
EmbedBitcodePass(bool IsThinLTO, bool EmitLTOSummary)
: IsThinLTO(IsThinLTO), EmitLTOSummary(EmitLTOSummary) {}
- LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &);
+ LLVM_ABI PreservedAnalyses run(Module &M,
+ ModuleSummaryIndexAnalysisManager &AM);
static bool isRequired() { return true; }
};
diff --git a/llvm/include/llvm/Transforms/IPO/ThinLTOBitcodeWriter.h b/llvm/include/llvm/Transforms/IPO/ThinLTOBitcodeWriter.h
index a21db26f1edbc..5be54e01987e9 100644
--- a/llvm/include/llvm/Transforms/IPO/ThinLTOBitcodeWriter.h
+++ b/llvm/include/llvm/Transforms/IPO/ThinLTOBitcodeWriter.h
@@ -22,22 +22,26 @@
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);
+ LLVM_ABI PreservedAnalyses run(Module &M,
+ ModuleSummaryIndexAnalysisManager &AM);
static bool isRequired() { return true; }
};
diff --git a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
index a317ac471a231..1663205f31e1d 100644
--- a/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
+++ b/llvm/lib/Analysis/ModuleSummaryAnalysis.cpp
@@ -43,6 +43,7 @@
#include "llvm/IR/Metadata.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/ModuleSummaryIndex.h"
+#include "llvm/IR/PassManager.h"
#include "llvm/IR/Use.h"
#include "llvm/IR/User.h"
#include "llvm/InitializePasses.h"
@@ -934,7 +935,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 +979,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 +989,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 +1034,8 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex(
SmallVector<ValueInfo, 0>{});
Index.addGlobalValueSummary(*GV, std::move(Summary));
}
- });
+ },
+ TM);
}
bool IsThinLTO = true;
@@ -1144,10 +1148,11 @@ ModuleSummaryIndex llvm::buildModuleSummaryIndex(
AnalysisKey ModuleSummaryIndexAnalysis::Key;
-ModuleSummaryIndex
-ModuleSummaryIndexAnalysis::run(Module &M, ModuleAnalysisManager &AM) {
- ProfileSummaryInfo &PSI = AM.getResult<ProfileSummaryAnalysis>(M);
- auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
+ModuleSummaryIndex ModuleSummaryIndexAnalysis::run(
+ Module &M, ModuleSummaryIndexAnalysisManager &AM, const TargetMachine *TM) {
+ ProfileSummaryInfo &PSI = AM.getResult<ProfileSummaryAnalysis>(M, TM);
+ auto &FAM =
+ AM.getResult<FunctionAnalysisManagerModuleProxy>(M, TM).getManager();
bool NeedSSI = needsParamAccessSummary(M);
return buildModuleSummaryIndex(
M,
@@ -1155,7 +1160,7 @@ ModuleSummaryIndexAnalysis::run(Module &M, ModuleAnalysisManager &AM) {
return &FAM.getResult<BlockFrequencyAnalysis>(
*const_cast<Function *>(&F));
},
- &PSI,
+ &PSI, TM,
[&FAM, NeedSSI](const Function &F) -> const StackSafetyInfo * {
return NeedSSI ? &FAM.getResult<StackSafetyAnalysis>(
const_cast<Function &>(F))
@@ -1190,7 +1195,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 2a2dd085a9461..d03086e147ae6 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
@@ -5364,13 +5364,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);
}
@@ -5412,7 +5413,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;
}
@@ -5472,7 +5473,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);
@@ -5493,7 +5495,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);
}
}
@@ -5679,11 +5681,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..4742d5a6e0f85 100644
--- a/llvm/lib/Bitcode/Writer/BitcodeWriterPass.cpp
+++ b/llvm/lib/Bitcode/Writer/BitcodeWriterPass.cpp
@@ -11,21 +11,25 @@
//===----------------------------------------------------------------------===//
#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"
#include "llvm/Pass.h"
using namespace llvm;
-PreservedAnalyses BitcodeWriterPass::run(Module &M, ModuleAnalysisManager &AM) {
+PreservedAnalyses
+BitcodeWriterPass::run(Module &M, ModuleSummaryIndexAnalysisManager &AM) {
M.removeDebugIntrinsicDeclarations();
const ModuleSummaryIndex *Index =
- EmitSummaryIndex ? &(AM.getResult<ModuleSummaryIndexAnalysis>(M))
+ EmitSummaryIndex ? &(AM.getResult<ModuleSummaryIndexAnalysis>(M, TM))
: nullptr;
- WriteBitcodeToFile(M, OS, ShouldPreserveUseListOrder, Index, EmitModuleHash);
-
+ WriteBitcodeToFile(M, OS, ShouldPreserveUseListOrder, Index, EmitModuleHash,
+ /*ModHash=*/nullptr, TM);
return PreservedAnalyses::all();
}
@@ -33,6 +37,7 @@ namespace {
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
@@ -40,9 +45,10 @@ namespace {
initializeWriteBitcodePassPass(*PassRegistry::getPassRegistry());
}
- explicit WriteBitcodePass(raw_ostream &o, bool ShouldPreserveUseListOrder)
+ explicit WriteBitcodePass(raw_ostream &o, bool ShouldPreserveUseListOrder,
+ const TargetMachine *TM = nullptr)
: ModulePass(ID), OS(o),
- ShouldPreserveUseListOrder(ShouldPreserveUseListOrder) {
+ ShouldPreserveUseListOrder(ShouldPreserveUseListOrder), TM(TM) {
initializeWriteBitcodePassPass(*PassRegistry::getPassRegistry());
}
@@ -52,7 +58,7 @@ namespace {
M.removeDebugIntrinsicDeclarations();
WriteBitcodeToFile(M, OS, ShouldPreserveUseListOrder, /*Index=*/nullptr,
- /*EmitModuleHash=*/false);
+ /*GenerateHash=*/false, /*ModHash=*/nullptr, TM);
return false;
}
@@ -70,8 +76,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 2579fa37935f0..9c17c7246aada 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..ac2e389b86ec4 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.
@@ -86,6 +90,9 @@ initializeRecordStreamer(const Module &M,
return;
MCTargetOptions MCOptions;
+ if (TM)
+ MCOptions = TM->Options.MCOptions;
+
std::unique_ptr<MCAsmInfo> MAI(T->createMCAsmInfo(*MRI, TT.str(), MCOptions));
if (!MAI)
return;
@@ -104,6 +111,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 +147,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/EmbedBitcodePass.cpp b/llvm/lib/Transforms/IPO/EmbedBitcodePass.cpp
index f02256f8a83b9..2127ed360adf0 100644
--- a/llvm/lib/Transforms/IPO/EmbedBitcodePass.cpp
+++ b/llvm/lib/Transforms/IPO/EmbedBitcodePass.cpp
@@ -22,7 +22,8 @@
using namespace llvm;
-PreservedAnalyses EmbedBitcodePass::run(Module &M, ModuleAnalysisManager &AM) {
+PreservedAnalyses EmbedBitcodePass::run(Module &M,
+ ModuleSummaryIndexAnalysisManager &AM) {
if (M.getGlobalVariable("llvm.embedded.module", /*AllowInternal=*/true))
reportFatalUsageError("Can only embed the module once");
diff --git a/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp b/llvm/lib/Transforms/IPO/ThinLTOBitcodeWriter.cpp
index e276376f21583..ec6240ca55171 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,21 +572,21 @@ 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;
}
} // anonymous namespace
PreservedAnalyses
-llvm::ThinLTOBitcodeWriterPass::run(Module &M, ModuleAnalysisManager &AM) {
+llvm::ThinLTOBitcodeWriterPass::run(Module &M, ModuleSummaryIndexAnalysisManager &AM) {
FunctionAnalysisManager &FAM =
- AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
+ AM.getResult<FunctionAnalysisManagerModuleProxy>(M, TM).getManager();
M.removeDebugIntrinsicDeclarations();
@@ -591,8 +595,8 @@ llvm::ThinLTOBitcodeWriterPass::run(Module &M, ModuleAnalysisManager &AM) {
[&FAM](Function &F) -> AAResults & {
return FAM.getResult<AAManager>(F);
},
- M, &AM.getResult<ModuleSummaryIndexAnalysis>(M),
- ShouldPreserveUseListOrder);
+ M, &AM.getResult<ModuleSummaryIndexAnalysis>(M, TM),
+ ShouldPreserveUseListOrder, TM);
return Changed ? PreservedAnalyses::none() : PreservedAnalyses::all();
}
More information about the llvm-commits
mailing list