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.
118 lines
3.9 KiB
C++
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
|