diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2023-07-26 19:03:47 +0000 |
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2023-07-26 19:04:23 +0000 |
| commit | 7fa27ce4a07f19b07799a767fc29416f3b625afb (patch) | |
| tree | 27825c83636c4de341eb09a74f49f5d38a15d165 /clang/lib/CodeGen/CodeGenAction.cpp | |
| parent | e3b557809604d036af6e00c60f012c2025b59a5e (diff) | |
Diffstat (limited to 'clang/lib/CodeGen/CodeGenAction.cpp')
| -rw-r--r-- | clang/lib/CodeGen/CodeGenAction.cpp | 159 |
1 files changed, 100 insertions, 59 deletions
diff --git a/clang/lib/CodeGen/CodeGenAction.cpp b/clang/lib/CodeGen/CodeGenAction.cpp index 2b219267869e..a3b72381d73f 100644 --- a/clang/lib/CodeGen/CodeGenAction.cpp +++ b/clang/lib/CodeGen/CodeGenAction.cpp @@ -7,6 +7,7 @@ //===----------------------------------------------------------------------===// #include "clang/CodeGen/CodeGenAction.h" +#include "CGCall.h" #include "CodeGenModule.h" #include "CoverageMappingGen.h" #include "MacroPPCallbacks.h" @@ -86,7 +87,7 @@ namespace clang { }; static void reportOptRecordError(Error E, DiagnosticsEngine &Diags, - const CodeGenOptions CodeGenOpts) { + const CodeGenOptions &CodeGenOpts) { handleAllErrors( std::move(E), [&](const LLVMRemarkSetupFileError &E) { @@ -115,6 +116,7 @@ namespace clang { const LangOptions &LangOpts; std::unique_ptr<raw_pwrite_stream> AsmOutStream; ASTContext *Context; + IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS; Timer LLVMIRGeneration; unsigned LLVMIRGenerationRefCount; @@ -147,7 +149,7 @@ namespace clang { public: BackendConsumer(BackendAction Action, DiagnosticsEngine &Diags, - IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS, + IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS, const HeaderSearchOptions &HeaderSearchOpts, const PreprocessorOptions &PPOpts, const CodeGenOptions &CodeGenOpts, @@ -158,10 +160,10 @@ namespace clang { CoverageSourceInfo *CoverageInfo = nullptr) : Diags(Diags), Action(Action), HeaderSearchOpts(HeaderSearchOpts), CodeGenOpts(CodeGenOpts), TargetOpts(TargetOpts), LangOpts(LangOpts), - AsmOutStream(std::move(OS)), Context(nullptr), + AsmOutStream(std::move(OS)), Context(nullptr), FS(VFS), LLVMIRGeneration("irgen", "LLVM IR Generation Time"), LLVMIRGenerationRefCount(0), - Gen(CreateLLVMCodeGen(Diags, InFile, std::move(FS), HeaderSearchOpts, + Gen(CreateLLVMCodeGen(Diags, InFile, std::move(VFS), HeaderSearchOpts, PPOpts, CodeGenOpts, C, CoverageInfo)), LinkModules(std::move(LinkModules)) { TimerIsEnabled = CodeGenOpts.TimePasses; @@ -173,7 +175,7 @@ namespace clang { // to use the clang diagnostic handler for IR input files. It avoids // initializing the OS field. BackendConsumer(BackendAction Action, DiagnosticsEngine &Diags, - IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS, + IntrusiveRefCntPtr<llvm::vfs::FileSystem> VFS, const HeaderSearchOptions &HeaderSearchOpts, const PreprocessorOptions &PPOpts, const CodeGenOptions &CodeGenOpts, @@ -183,10 +185,10 @@ namespace clang { CoverageSourceInfo *CoverageInfo = nullptr) : Diags(Diags), Action(Action), HeaderSearchOpts(HeaderSearchOpts), CodeGenOpts(CodeGenOpts), TargetOpts(TargetOpts), LangOpts(LangOpts), - Context(nullptr), + Context(nullptr), FS(VFS), LLVMIRGeneration("irgen", "LLVM IR Generation Time"), LLVMIRGenerationRefCount(0), - Gen(CreateLLVMCodeGen(Diags, "", std::move(FS), HeaderSearchOpts, + Gen(CreateLLVMCodeGen(Diags, "", std::move(VFS), HeaderSearchOpts, PPOpts, CodeGenOpts, C, CoverageInfo)), LinkModules(std::move(LinkModules)), CurLinkModule(Module) { TimerIsEnabled = CodeGenOpts.TimePasses; @@ -261,15 +263,17 @@ namespace clang { } // Links each entry in LinkModules into our module. Returns true on error. - bool LinkInModules() { + bool LinkInModules(llvm::Module *M) { for (auto &LM : LinkModules) { + assert(LM.Module && "LinkModule does not actually have a module"); if (LM.PropagateAttrs) for (Function &F : *LM.Module) { // Skip intrinsics. Keep consistent with how intrinsics are created // in LLVM IR. if (F.isIntrinsic()) continue; - Gen->CGM().addDefaultFunctionDefinitionAttributes(F); + CodeGen::mergeDefaultFunctionDefinitionAttributes( + F, CodeGenOpts, LangOpts, TargetOpts, LM.Internalize); } CurLinkModule = LM.Module.get(); @@ -277,20 +281,20 @@ namespace clang { bool Err; if (LM.Internalize) { Err = Linker::linkModules( - *getModule(), std::move(LM.Module), LM.LinkFlags, + *M, std::move(LM.Module), LM.LinkFlags, [](llvm::Module &M, const llvm::StringSet<> &GVS) { internalizeModule(M, [&GVS](const llvm::GlobalValue &GV) { return !GV.hasName() || (GVS.count(GV.getName()) == 0); }); }); } else { - Err = Linker::linkModules(*getModule(), std::move(LM.Module), - LM.LinkFlags); + Err = Linker::linkModules(*M, std::move(LM.Module), LM.LinkFlags); } if (Err) return true; } + LinkModules.clear(); return false; // success } @@ -353,7 +357,7 @@ namespace clang { } // Link each LinkModule into our module. - if (LinkInModules()) + if (LinkInModules(getModule())) return; for (auto &F : getModule()->functions()) { @@ -381,7 +385,7 @@ namespace clang { EmitBackendOutput(Diags, HeaderSearchOpts, CodeGenOpts, TargetOpts, LangOpts, C.getTargetInfo().getDataLayoutString(), - getModule(), Action, std::move(AsmOutStream)); + getModule(), Action, FS, std::move(AsmOutStream)); Ctx.setDiagnosticHandler(std::move(OldDiagnosticHandler)); @@ -631,9 +635,8 @@ BackendConsumer::StackSizeDiagHandler(const llvm::DiagnosticInfoStackSize &D) { return false; Diags.Report(*Loc, diag::warn_fe_frame_larger_than) - << D.getStackSize() - << D.getStackLimit() - << llvm::demangle(D.getFunction().getName().str()); + << D.getStackSize() << D.getStackLimit() + << llvm::demangle(D.getFunction().getName()); return true; } @@ -647,7 +650,7 @@ bool BackendConsumer::ResourceLimitDiagHandler( Diags.Report(*Loc, DiagID) << D.getResourceName() << D.getResourceSize() << D.getResourceLimit() - << llvm::demangle(D.getFunction().getName().str()); + << llvm::demangle(D.getFunction().getName()); return true; } @@ -852,7 +855,7 @@ void BackendConsumer::DontCallDiagHandler(const DiagnosticInfoDontCall &D) { Diags.Report(LocCookie, D.getSeverity() == DiagnosticSeverity::DS_Error ? diag::err_fe_backend_error_attr : diag::warn_fe_backend_warning_attr) - << llvm::demangle(D.getFunctionName().str()) << D.getNote(); + << llvm::demangle(D.getFunctionName()) << D.getNote(); } void BackendConsumer::MisExpectDiagHandler( @@ -990,6 +993,36 @@ CodeGenAction::~CodeGenAction() { delete VMContext; } +bool CodeGenAction::loadLinkModules(CompilerInstance &CI) { + if (!LinkModules.empty()) + return false; + + for (const CodeGenOptions::BitcodeFileToLink &F : + CI.getCodeGenOpts().LinkBitcodeFiles) { + auto BCBuf = CI.getFileManager().getBufferForFile(F.Filename); + if (!BCBuf) { + CI.getDiagnostics().Report(diag::err_cannot_open_file) + << F.Filename << BCBuf.getError().message(); + LinkModules.clear(); + return true; + } + + Expected<std::unique_ptr<llvm::Module>> ModuleOrErr = + getOwningLazyBitcodeModule(std::move(*BCBuf), *VMContext); + if (!ModuleOrErr) { + handleAllErrors(ModuleOrErr.takeError(), [&](ErrorInfoBase &EIB) { + CI.getDiagnostics().Report(diag::err_cannot_open_file) + << F.Filename << EIB.message(); + }); + LinkModules.clear(); + return true; + } + LinkModules.push_back({std::move(ModuleOrErr.get()), F.PropagateAttrs, + F.Internalize, F.LinkFlags}); + } + return false; +} + bool CodeGenAction::hasIRSupport() const { return true; } void CodeGenAction::EndSourceFileAction() { @@ -1044,33 +1077,9 @@ CodeGenAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { if (BA != Backend_EmitNothing && !OS) return nullptr; - VMContext->setOpaquePointers(CI.getCodeGenOpts().OpaquePointers); - // Load bitcode modules to link with, if we need to. - if (LinkModules.empty()) - for (const CodeGenOptions::BitcodeFileToLink &F : - CI.getCodeGenOpts().LinkBitcodeFiles) { - auto BCBuf = CI.getFileManager().getBufferForFile(F.Filename); - if (!BCBuf) { - CI.getDiagnostics().Report(diag::err_cannot_open_file) - << F.Filename << BCBuf.getError().message(); - LinkModules.clear(); - return nullptr; - } - - Expected<std::unique_ptr<llvm::Module>> ModuleOrErr = - getOwningLazyBitcodeModule(std::move(*BCBuf), *VMContext); - if (!ModuleOrErr) { - handleAllErrors(ModuleOrErr.takeError(), [&](ErrorInfoBase &EIB) { - CI.getDiagnostics().Report(diag::err_cannot_open_file) - << F.Filename << EIB.message(); - }); - LinkModules.clear(); - return nullptr; - } - LinkModules.push_back({std::move(ModuleOrErr.get()), F.PropagateAttrs, - F.Internalize, F.LinkFlags}); - } + if (loadLinkModules(CI)) + return nullptr; CoverageSourceInfo *CoverageInfo = nullptr; // Add the preprocessor callback only when the coverage mapping is generated. @@ -1103,7 +1112,14 @@ CodeGenAction::loadModule(MemoryBufferRef MBRef) { CompilerInstance &CI = getCompilerInstance(); SourceManager &SM = CI.getSourceManager(); - VMContext->setOpaquePointers(CI.getCodeGenOpts().OpaquePointers); + auto DiagErrors = [&](Error E) -> std::unique_ptr<llvm::Module> { + unsigned DiagID = + CI.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Error, "%0"); + handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) { + CI.getDiagnostics().Report(DiagID) << EIB.message(); + }); + return {}; + }; // For ThinLTO backend invocations, ensure that the context // merges types based on ODR identifiers. We also need to read @@ -1111,15 +1127,6 @@ CodeGenAction::loadModule(MemoryBufferRef MBRef) { if (!CI.getCodeGenOpts().ThinLTOIndexFile.empty()) { VMContext->enableDebugTypeODRUniquing(); - auto DiagErrors = [&](Error E) -> std::unique_ptr<llvm::Module> { - unsigned DiagID = - CI.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Error, "%0"); - handleAllErrors(std::move(E), [&](ErrorInfoBase &EIB) { - CI.getDiagnostics().Report(DiagID) << EIB.message(); - }); - return {}; - }; - Expected<std::vector<BitcodeModule>> BMsOrErr = getBitcodeModuleList(MBRef); if (!BMsOrErr) return DiagErrors(BMsOrErr.takeError()); @@ -1140,10 +1147,39 @@ CodeGenAction::loadModule(MemoryBufferRef MBRef) { return std::move(*MOrErr); } + // Load bitcode modules to link with, if we need to. + if (loadLinkModules(CI)) + return nullptr; + + // Handle textual IR and bitcode file with one single module. llvm::SMDiagnostic Err; if (std::unique_ptr<llvm::Module> M = parseIR(MBRef, Err, *VMContext)) return M; + // If MBRef is a bitcode with multiple modules (e.g., -fsplit-lto-unit + // output), place the extra modules (actually only one, a regular LTO module) + // into LinkModules as if we are using -mlink-bitcode-file. + Expected<std::vector<BitcodeModule>> BMsOrErr = getBitcodeModuleList(MBRef); + if (BMsOrErr && BMsOrErr->size()) { + std::unique_ptr<llvm::Module> FirstM; + for (auto &BM : *BMsOrErr) { + Expected<std::unique_ptr<llvm::Module>> MOrErr = + BM.parseModule(*VMContext); + if (!MOrErr) + return DiagErrors(MOrErr.takeError()); + if (FirstM) + LinkModules.push_back({std::move(*MOrErr), /*PropagateAttrs=*/false, + /*Internalize=*/false, /*LinkFlags=*/{}}); + else + FirstM = std::move(*MOrErr); + } + if (FirstM) + return FirstM; + } + // If BMsOrErr fails, consume the error and use the error message from + // parseIR. + consumeError(BMsOrErr.takeError()); + // Translate from the diagnostic info to the SourceManager location if // available. // TODO: Unify this with ConvertBackendLocation() @@ -1219,6 +1255,11 @@ void CodeGenAction::ExecuteAction() { CI.getCodeGenOpts(), CI.getTargetOpts(), CI.getLangOpts(), TheModule.get(), std::move(LinkModules), *VMContext, nullptr); + + // Link in each pending link module. + if (Result.LinkInModules(&*TheModule)) + return; + // PR44896: Force DiscardValueNames as false. DiscardValueNames cannot be // true here because the valued names are needed for reading textual IR. Ctx.setDiscardValueNames(false); @@ -1238,10 +1279,10 @@ void CodeGenAction::ExecuteAction() { std::unique_ptr<llvm::ToolOutputFile> OptRecordFile = std::move(*OptRecordFileOrErr); - EmitBackendOutput(Diagnostics, CI.getHeaderSearchOpts(), CodeGenOpts, - TargetOpts, CI.getLangOpts(), - CI.getTarget().getDataLayoutString(), TheModule.get(), BA, - std::move(OS)); + EmitBackendOutput( + Diagnostics, CI.getHeaderSearchOpts(), CodeGenOpts, TargetOpts, + CI.getLangOpts(), CI.getTarget().getDataLayoutString(), TheModule.get(), + BA, CI.getFileManager().getVirtualFileSystemPtr(), std::move(OS)); if (OptRecordFile) OptRecordFile->keep(); } |
