[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