Skip to content

Make MMIWP not have ownership over MMI + Make MMI Only Use an External MCContext #105541

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 8 commits into
base: main
Choose a base branch
from
16 changes: 13 additions & 3 deletions clang/lib/CodeGen/BackendUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "llvm/Bitcode/BitcodeReader.h"
#include "llvm/Bitcode/BitcodeWriter.h"
#include "llvm/Bitcode/BitcodeWriterPass.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/RegAllocRegistry.h"
#include "llvm/CodeGen/SchedulerRegistry.h"
#include "llvm/CodeGen/TargetSubtargetInfo.h"
Expand Down Expand Up @@ -168,7 +169,8 @@ class EmitAssemblyHelper {
///
/// \return True on success.
bool AddEmitPasses(legacy::PassManager &CodeGenPasses, BackendAction Action,
raw_pwrite_stream &OS, raw_pwrite_stream *DwoOS);
MachineModuleInfo &MMI, raw_pwrite_stream &OS,
raw_pwrite_stream *DwoOS);

std::unique_ptr<llvm::ToolOutputFile> openOutputFile(StringRef Path) {
std::error_code EC;
Expand Down Expand Up @@ -614,6 +616,7 @@ void EmitAssemblyHelper::CreateTargetMachine(bool MustCreateTM) {

bool EmitAssemblyHelper::AddEmitPasses(legacy::PassManager &CodeGenPasses,
BackendAction Action,
MachineModuleInfo &MMI,
raw_pwrite_stream &OS,
raw_pwrite_stream *DwoOS) {
// Add LibraryInfo.
Expand All @@ -625,7 +628,7 @@ bool EmitAssemblyHelper::AddEmitPasses(legacy::PassManager &CodeGenPasses,
// this also adds codegenerator level optimization passes.
CodeGenFileType CGFT = getCodeGenFileType(Action);

if (TM->addPassesToEmitFile(CodeGenPasses, OS, DwoOS, CGFT,
if (TM->addPassesToEmitFile(CodeGenPasses, OS, DwoOS, CGFT, MMI,
/*DisableVerify=*/!CodeGenOpts.VerifyModule)) {
Diags.Report(diag::err_fe_unable_to_interface_with_target);
return false;
Expand Down Expand Up @@ -1162,6 +1165,8 @@ void EmitAssemblyHelper::RunCodegenPipeline(
// does not work with the codegen pipeline.
// FIXME: make the new PM work with the codegen pipeline.
legacy::PassManager CodeGenPasses;
std::unique_ptr<llvm::MCContext> MCCtx;
std::unique_ptr<llvm::MachineModuleInfo> MMI;

// Append any output we need to the pass manager.
switch (Action) {
Expand All @@ -1175,7 +1180,12 @@ void EmitAssemblyHelper::RunCodegenPipeline(
if (!DwoOS)
return;
}
if (!AddEmitPasses(CodeGenPasses, Action, *OS,
MCCtx = std::make_unique<MCContext>(
TM->getTargetTriple(), TM->getMCAsmInfo(), TM->getMCRegisterInfo(),
TM->getMCSubtargetInfo(), nullptr, &TM->Options.MCOptions, false);

MMI = TM->createMachineModuleInfo(*MCCtx);
if (!AddEmitPasses(CodeGenPasses, Action, *MMI, *OS,
DwoOS ? &DwoOS->os() : nullptr))
// FIXME: Should we handle this error differently?
return;
Expand Down
11 changes: 9 additions & 2 deletions clang/lib/Interpreter/DeviceOffload.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,10 @@
#include "clang/CodeGen/ModuleBuilder.h"
#include "clang/Frontend/CompilerInstance.h"

#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Module.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Target/TargetMachine.h"

Expand Down Expand Up @@ -88,8 +90,13 @@ llvm::Expected<llvm::StringRef> IncrementalCUDADeviceParser::GeneratePTX() {
llvm::raw_svector_ostream dest(PTXCode);

llvm::legacy::PassManager PM;
if (TargetMachine->addPassesToEmitFile(PM, dest, nullptr,
llvm::CodeGenFileType::AssemblyFile)) {
llvm::MCContext MCCtx(
TargetMachine->getTargetTriple(), TargetMachine->getMCAsmInfo(),
TargetMachine->getMCRegisterInfo(), TargetMachine->getMCSubtargetInfo(),
nullptr, &TargetMachine->Options.MCOptions, false);
auto MMI = TargetMachine->createMachineModuleInfo(MCCtx);
if (TargetMachine->addPassesToEmitFile(
PM, dest, nullptr, llvm::CodeGenFileType::AssemblyFile, *MMI)) {
return llvm::make_error<llvm::StringError>(
"NVPTX backend cannot produce PTX code.",
llvm::inconvertibleErrorCode());
Expand Down
11 changes: 9 additions & 2 deletions clang/lib/Interpreter/Wasm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@
#include "Wasm.h"
#include "IncrementalExecutor.h"

#include <llvm/CodeGen/MachineModuleInfo.h>
#include <llvm/IR/LegacyPassManager.h>
#include <llvm/IR/Module.h>
#include <llvm/MC/MCContext.h>
#include <llvm/MC/TargetRegistry.h>
#include <llvm/Target/TargetMachine.h>

Expand Down Expand Up @@ -57,8 +59,13 @@ llvm::Error WasmIncrementalExecutor::addModule(PartialTranslationUnit &PTU) {
llvm::raw_fd_ostream OutputFile(llvm::StringRef(OutputFileName), Error);

llvm::legacy::PassManager PM;
if (TargetMachine->addPassesToEmitFile(PM, OutputFile, nullptr,
llvm::CodeGenFileType::ObjectFile)) {
llvm::MCContext MCCtx(
TargetMachine->getTargetTriple(), TargetMachine->getMCAsmInfo(),
TargetMachine->getMCRegisterInfo(), TargetMachine->getMCSubtargetInfo(),
nullptr, &TargetMachine->Options.MCOptions, false);
auto MMI = TargetMachine->createMachineModuleInfo(MCCtx);
if (TargetMachine->addPassesToEmitFile(
PM, OutputFile, nullptr, llvm::CodeGenFileType::ObjectFile, *MMI)) {
return llvm::make_error<llvm::StringError>(
"Wasm backend cannot produce object.", llvm::inconvertibleErrorCode());
}
Expand Down
8 changes: 7 additions & 1 deletion clang/tools/clang-linker-wrapper/ClangLinkerWrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@
#include "llvm/BinaryFormat/Magic.h"
#include "llvm/Bitcode/BitcodeWriter.h"
#include "llvm/CodeGen/CommandFlags.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/Frontend/Offloading/OffloadWrapper.h"
#include "llvm/Frontend/Offloading/Utility.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DiagnosticPrinter.h"
#include "llvm/IR/Module.h"
#include "llvm/IRReader/IRReader.h"
#include "llvm/LTO/LTO.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/TargetRegistry.h"
#include "llvm/Object/Archive.h"
#include "llvm/Object/ArchiveWriter.h"
Expand Down Expand Up @@ -1051,10 +1053,14 @@ Expected<StringRef> compileModule(Module &M, OffloadKind Kind) {
auto OS = std::make_unique<llvm::raw_fd_ostream>(FD, true);

legacy::PassManager CodeGenPasses;
MCContext MCCtx(TM->getTargetTriple(), TM->getMCAsmInfo(),
TM->getMCRegisterInfo(), TM->getMCSubtargetInfo(), nullptr,
&TM->Options.MCOptions, false);
auto MMI = TM->createMachineModuleInfo(MCCtx);
TargetLibraryInfoImpl TLII(Triple(M.getTargetTriple()));
CodeGenPasses.add(new TargetLibraryInfoWrapperPass(TLII));
if (TM->addPassesToEmitFile(CodeGenPasses, *OS, nullptr,
CodeGenFileType::ObjectFile))
CodeGenFileType::ObjectFile, *MMI))
return createStringError("Failed to execute host backend");
CodeGenPasses.run(M);

Expand Down
8 changes: 7 additions & 1 deletion flang/lib/Frontend/FrontendActions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,15 @@
#include "llvm/Analysis/TargetLibraryInfo.h"
#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/Bitcode/BitcodeWriterPass.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/CodeGen/MachineOptimizationRemarkEmitter.h"
#include "llvm/IR/LLVMRemarkStreamer.h"
#include "llvm/IR/LegacyPassManager.h"
#include "llvm/IR/Verifier.h"
#include "llvm/IRPrinter/IRPrintingPasses.h"
#include "llvm/IRReader/IRReader.h"
#include "llvm/Linker/Linker.h"
#include "llvm/MC/MCContext.h"
#include "llvm/Object/OffloadBinary.h"
#include "llvm/Passes/PassBuilder.h"
#include "llvm/Passes/PassPlugin.h"
Expand Down Expand Up @@ -944,7 +946,11 @@ static void generateMachineCodeOrAssemblyImpl(clang::DiagnosticsEngine &diags,
llvm::CodeGenFileType cgft = (act == BackendActionTy::Backend_EmitAssembly)
? llvm::CodeGenFileType::AssemblyFile
: llvm::CodeGenFileType::ObjectFile;
if (tm.addPassesToEmitFile(codeGenPasses, os, nullptr, cgft)) {
llvm::MCContext mcCtx(tm.getTargetTriple(), tm.getMCAsmInfo(),
tm.getMCRegisterInfo(), tm.getMCSubtargetInfo(),
nullptr, &tm.Options.MCOptions, false);
auto mmi = tm.createMachineModuleInfo(mcCtx);
if (tm.addPassesToEmitFile(codeGenPasses, os, nullptr, cgft, *mmi)) {
unsigned diagID =
diags.getCustomDiagID(clang::DiagnosticsEngine::Error,
"emission of this file type is not supported");
Expand Down
31 changes: 11 additions & 20 deletions llvm/include/llvm/CodeGen/MachineModuleInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,11 @@ class MachineModuleInfo {
friend class MachineModuleInfoWrapperPass;
friend class MachineModuleAnalysis;

/// This is the TargetMachine used for the entire code generator.
const LLVMTargetMachine &TM;

/// This is the MCContext used for the entire code generator.
MCContext Context;
// This is an external context, that if assigned, will be used instead of the
// internal context.
MCContext *ExternalContext = nullptr;
MCContext &Context;

/// This is the LLVM Module being worked on.
const Module *TheModule = nullptr;
Expand All @@ -106,15 +104,14 @@ class MachineModuleInfo {
const Function *LastRequest = nullptr; ///< Used for shortcut/cache.
MachineFunction *LastResult = nullptr; ///< Used for shortcut/cache.

MachineModuleInfo &operator=(MachineModuleInfo &&MMII) = delete;

public:
explicit MachineModuleInfo(const LLVMTargetMachine *TM = nullptr);
explicit MachineModuleInfo(const LLVMTargetMachine &TM, MCContext &Context);

explicit MachineModuleInfo(const LLVMTargetMachine *TM,
MCContext *ExtContext);
/// Deleted copy constructor
MachineModuleInfo(MachineModuleInfo &MMI) = delete;

MachineModuleInfo(MachineModuleInfo &&MMII);
/// Deleted copy assignment operator
MachineModuleInfo &operator=(MachineModuleInfo &MMII) = delete;

~MachineModuleInfo();

Expand All @@ -123,12 +120,8 @@ class MachineModuleInfo {

const LLVMTargetMachine &getTarget() const { return TM; }

const MCContext &getContext() const {
return ExternalContext ? *ExternalContext : Context;
}
MCContext &getContext() {
return ExternalContext ? *ExternalContext : Context;
}
const MCContext &getContext() const { return Context; }
MCContext &getContext() { return Context; }

const Module *getModule() const { return TheModule; }

Expand Down Expand Up @@ -169,14 +162,12 @@ class MachineModuleInfo {
}; // End class MachineModuleInfo

class MachineModuleInfoWrapperPass : public ImmutablePass {
MachineModuleInfo MMI;
MachineModuleInfo &MMI;

public:
static char ID; // Pass identification, replacement for typeid
explicit MachineModuleInfoWrapperPass(const LLVMTargetMachine *TM = nullptr);

explicit MachineModuleInfoWrapperPass(const LLVMTargetMachine *TM,
MCContext *ExtContext);
explicit MachineModuleInfoWrapperPass(MachineModuleInfo &MMI);

// Initialization and Finalization
bool doInitialization(Module &) override;
Expand Down
57 changes: 29 additions & 28 deletions llvm/include/llvm/Target/TargetMachine.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ using ModulePassManager = PassManager<Module>;

class Function;
class GlobalValue;
class MachineModuleInfoWrapperPass;
class MachineModuleInfo;
class Mangler;
class MCAsmInfo;
class MCContext;
Expand Down Expand Up @@ -375,27 +375,27 @@ class TargetMachine {
/// with the new pass manager. Only affects the "default" AAManager.
virtual void registerDefaultAliasAnalyses(AAManager &) {}

/// Creates a new instance of \c MachineModuleInfo to be used for code
/// generation for this \c TargetMachine
virtual std::unique_ptr<MachineModuleInfo>
createMachineModuleInfo(MCContext &Ctx) const = 0;

/// Add passes to the specified pass manager to get the specified file
/// emitted. Typically this will involve several steps of code generation.
/// emitted. Typically this will involve several steps of code generation.
/// This method should return true if emission of this file type is not
/// supported, or false on success.
/// \p MMIWP is an optional parameter that, if set to non-nullptr,
/// will be used to set the MachineModuloInfo for this PM.
virtual bool
addPassesToEmitFile(PassManagerBase &, raw_pwrite_stream &,
raw_pwrite_stream *, CodeGenFileType,
bool /*DisableVerify*/ = true,
MachineModuleInfoWrapperPass *MMIWP = nullptr) {
/// \p MMI must be created externally before being passed to this function
virtual bool addPassesToEmitFile(PassManagerBase &, raw_pwrite_stream &,
raw_pwrite_stream *, CodeGenFileType,
MachineModuleInfo &MMI,
bool /*DisableVerify*/ = true) {
return true;
}

/// Add passes to the specified pass manager to get machine code emitted with
/// the MCJIT. This method returns true if machine code is not supported. It
/// fills the MCContext Ctx pointer which can be used to build custom
/// MCStreamer.
///
virtual bool addPassesToEmitMC(PassManagerBase &, MCContext *&,
raw_pwrite_stream &,
/// the MCJIT. This method returns true if machine code is not supported.
virtual bool addPassesToEmitMC(PassManagerBase &, raw_pwrite_stream &,
MachineModuleInfo &,
bool /*DisableVerify*/ = true) {
return true;
}
Expand Down Expand Up @@ -459,15 +459,18 @@ class LLVMTargetMachine : public TargetMachine {
/// for generating a pipeline of CodeGen passes.
virtual TargetPassConfig *createPassConfig(PassManagerBase &PM);

/// Creates a new instance of \c MachineModuleInfo to be used for code
/// generation for this \c TargetMachine
virtual std::unique_ptr<MachineModuleInfo>
createMachineModuleInfo(MCContext &Ctx) const override;

/// Add passes to the specified pass manager to get the specified file
/// emitted. Typically this will involve several steps of code generation.
/// \p MMIWP is an optional parameter that, if set to non-nullptr,
/// will be used to set the MachineModuloInfo for this PM.
bool
addPassesToEmitFile(PassManagerBase &PM, raw_pwrite_stream &Out,
raw_pwrite_stream *DwoOut, CodeGenFileType FileType,
bool DisableVerify = true,
MachineModuleInfoWrapperPass *MMIWP = nullptr) override;
/// emitted. Typically this will involve several steps of code generation.
/// \p MMI must be created externally before being passed to this function
bool addPassesToEmitFile(PassManagerBase &PM, raw_pwrite_stream &Out,
raw_pwrite_stream *DwoOut, CodeGenFileType FileType,
MachineModuleInfo &MMI,
bool DisableVerify = true) override;

virtual Error buildCodeGenPipeline(ModulePassManager &, raw_pwrite_stream &,
raw_pwrite_stream *, CodeGenFileType,
Expand All @@ -478,11 +481,9 @@ class LLVMTargetMachine : public TargetMachine {
}

/// Add passes to the specified pass manager to get machine code emitted with
/// the MCJIT. This method returns true if machine code is not supported. It
/// fills the MCContext Ctx pointer which can be used to build custom
/// MCStreamer.
bool addPassesToEmitMC(PassManagerBase &PM, MCContext *&Ctx,
raw_pwrite_stream &Out,
/// the MCJIT. This method returns true if machine code is not supported.
bool addPassesToEmitMC(PassManagerBase &PM, raw_pwrite_stream &Out,
MachineModuleInfo &MMI,
bool DisableVerify = true) override;

/// Returns true if the target is expected to pass all machine verifier
Expand Down
Loading
Loading