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_garvg...@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(); } _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits