llvm-project/llvm/lib/CodeGen/MachinePassManager.cpp
Arthur Eubanks bb531c9a00
[NewPM/Codegen] Move MachineModuleInfo ownership outside of analysis (#80937)
With the legacy pass manager, MachineModuleInfoWrapperPass owned the
MachineModuleInfo used in the codegen pipeline. It can do this since
it's an ImmutablePass that doesn't get invalidated.

However, with the new pass manager, it is legal for the
ModuleAnalysisManager to clear all of its analyses, regardless of if the
analysis does not want to be invalidated. So we must move ownership of
the MachineModuleInfo outside of the analysis (this is similar to
PassInstrumentation). For now, make the PassBuilder user register a
MachineModuleAnalysis that returns a reference to a MachineModuleInfo
that the user owns. Perhaps we can find a better place to own the
MachineModuleInfo to make using the codegen pass manager less cumbersome
in the future.
2024-02-07 09:15:43 -08:00

118 lines
3.9 KiB
C++

//===---------- MachinePassManager.cpp ------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file contains the pass management machinery for machine functions.
//
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/MachinePassManager.h"
#include "llvm/CodeGen/FreeMachineFunction.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/IR/PassManagerImpl.h"
using namespace llvm;
namespace llvm {
template class AllAnalysesOn<MachineFunction>;
template class AnalysisManager<MachineFunction>;
template class PassManager<MachineFunction>;
Error MachineFunctionPassManager::run(Module &M,
MachineFunctionAnalysisManager &MFAM) {
// MachineModuleAnalysis is a module analysis pass that is never invalidated
// because we don't run any module pass in codegen pipeline. This is very
// important because the codegen state is stored in MMI which is the analysis
// result of MachineModuleAnalysis. MMI should not be recomputed.
auto &MMI = MFAM.getResult<MachineModuleAnalysis>(M).getMMI();
(void)RequireCodeGenSCCOrder;
assert(!RequireCodeGenSCCOrder && "not implemented");
// M is unused here
PassInstrumentation PI = MFAM.getResult<PassInstrumentationAnalysis>(M);
// Add a PIC to verify machine functions.
if (VerifyMachineFunction) {
// No need to pop this callback later since MIR pipeline is flat which means
// current pipeline is the top-level pipeline. Callbacks are not used after
// current pipeline.
PI.pushBeforeNonSkippedPassCallback([&MFAM](StringRef PassID, Any IR) {
assert(llvm::any_cast<const MachineFunction *>(&IR));
const MachineFunction *MF = llvm::any_cast<const MachineFunction *>(IR);
assert(MF && "Machine function should be valid for printing");
std::string Banner = std::string("After ") + std::string(PassID);
verifyMachineFunction(&MFAM, Banner, *MF);
});
}
for (auto &F : InitializationFuncs) {
if (auto Err = F(M, MFAM))
return Err;
}
unsigned Idx = 0;
size_t Size = Passes.size();
do {
// Run machine module passes
for (; MachineModulePasses.count(Idx) && Idx != Size; ++Idx) {
if (!PI.runBeforePass<Module>(*Passes[Idx], M))
continue;
if (auto Err = MachineModulePasses.at(Idx)(M, MFAM))
return Err;
PI.runAfterPass(*Passes[Idx], M, PreservedAnalyses::all());
}
// Finish running all passes.
if (Idx == Size)
break;
// Run machine function passes
// Get index range of machine function passes.
unsigned Begin = Idx;
for (; !MachineModulePasses.count(Idx) && Idx != Size; ++Idx)
;
for (Function &F : M) {
// Do not codegen any 'available_externally' functions at all, they have
// definitions outside the translation unit.
if (F.hasAvailableExternallyLinkage())
continue;
MachineFunction &MF = MMI.getOrCreateMachineFunction(F);
for (unsigned I = Begin, E = Idx; I != E; ++I) {
auto *P = Passes[I].get();
if (!PI.runBeforePass<MachineFunction>(*P, MF))
continue;
// TODO: EmitSizeRemarks
PreservedAnalyses PassPA = P->run(MF, MFAM);
// MF is dangling after FreeMachineFunctionPass
if (P->name() != FreeMachineFunctionPass::name()) {
MFAM.invalidate(MF, PassPA);
PI.runAfterPass(*P, MF, PassPA);
}
}
}
} while (true);
for (auto &F : FinalizationFuncs) {
if (auto Err = F(M, MFAM))
return Err;
}
return Error::success();
}
} // namespace llvm