[llvm] [NewPM] Add `FunctionToMachineFunctionPassAdaptor` (PR #88711)
via llvm-commits
llvm-commits at lists.llvm.org
Tue Apr 16 01:39:17 PDT 2024
https://github.com/paperchalice updated https://github.com/llvm/llvm-project/pull/88711
>From d1d92e836d820b64c720effed5cc4cf6b1ed900e Mon Sep 17 00:00:00 2001
From: PaperChalice <liujunchang97 at outlook.com>
Date: Tue, 16 Apr 2024 15:00:37 +0800
Subject: [PATCH] [NewPM] Add `FunctionToMachineFunctionPassAdaptor`
---
.../include/llvm/CodeGen/MachinePassManager.h | 45 +++++++---
llvm/lib/CodeGen/MachinePassManager.cpp | 90 +++++++++++++++----
llvm/lib/Passes/PassBuilder.cpp | 1 +
llvm/unittests/CodeGen/PassManagerTest.cpp | 10 ++-
4 files changed, 115 insertions(+), 31 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/MachinePassManager.h b/llvm/include/llvm/CodeGen/MachinePassManager.h
index 4f0b6ba2b1e738..583da1df332ffe 100644
--- a/llvm/include/llvm/CodeGen/MachinePassManager.h
+++ b/llvm/include/llvm/CodeGen/MachinePassManager.h
@@ -129,16 +129,6 @@ class FunctionAnalysisManagerMachineFunctionProxy
Arg.FAM = nullptr;
}
- ~Result() {
- // FAM is cleared in a moved from state where there is nothing to do.
- if (!FAM)
- return;
-
- // Clear out the analysis manager if we're being destroyed -- it means we
- // didn't even see an invalidate call when we got invalidated.
- FAM->clear();
- }
-
Result &operator=(Result &&RHS) {
FAM = RHS.FAM;
// We have to null out the analysis manager in the moved-from state
@@ -211,8 +201,7 @@ class ModuleToMachineFunctionPassAdaptor
template <typename MachineFunctionPassT>
ModuleToMachineFunctionPassAdaptor
createModuleToMachineFunctionPassAdaptor(MachineFunctionPassT &&Pass) {
- using PassModelT = detail::PassModel<MachineFunction, MachineFunctionPassT,
- MachineFunctionAnalysisManager>;
+ using PassModelT = detail::MachinePassModel<MachineFunctionPassT>;
// Do not use make_unique, it causes too many template instantiations,
// causing terrible compile times.
return ModuleToMachineFunctionPassAdaptor(
@@ -220,6 +209,38 @@ createModuleToMachineFunctionPassAdaptor(MachineFunctionPassT &&Pass) {
new PassModelT(std::forward<MachineFunctionPassT>(Pass))));
}
+class FunctionToMachineFunctionPassAdaptor
+ : public PassInfoMixin<FunctionToMachineFunctionPassAdaptor> {
+public:
+ using PassConceptT =
+ detail::PassConcept<MachineFunction, MachineFunctionAnalysisManager>;
+
+ explicit FunctionToMachineFunctionPassAdaptor(
+ std::unique_ptr<PassConceptT> Pass)
+ : Pass(std::move(Pass)) {}
+
+ /// Runs the machine function pass across every function.
+ PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
+ void printPipeline(raw_ostream &OS,
+ function_ref<StringRef(StringRef)> MapClassName2PassName);
+
+ static bool isRequired() { return true; }
+
+private:
+ std::unique_ptr<PassConceptT> Pass;
+};
+
+template <typename MachineFunctionPassT>
+FunctionToMachineFunctionPassAdaptor
+createFunctionToMachineFunctionPassAdaptor(MachineFunctionPassT &&Pass) {
+ using PassModelT = detail::MachinePassModel<MachineFunctionPassT>;
+ // Do not use make_unique, it causes too many template instantiations,
+ // causing terrible compile times.
+ return FunctionToMachineFunctionPassAdaptor(
+ std::unique_ptr<FunctionToMachineFunctionPassAdaptor::PassConceptT>(
+ new PassModelT(std::forward<MachineFunctionPassT>(Pass))));
+}
+
template <>
template <typename PassT>
void PassManager<MachineFunction>::addPass(PassT &&Pass) {
diff --git a/llvm/lib/CodeGen/MachinePassManager.cpp b/llvm/lib/CodeGen/MachinePassManager.cpp
index 2763193b2c306b..3885ebddc263bd 100644
--- a/llvm/lib/CodeGen/MachinePassManager.cpp
+++ b/llvm/lib/CodeGen/MachinePassManager.cpp
@@ -11,6 +11,8 @@
//===----------------------------------------------------------------------===//
#include "llvm/CodeGen/MachinePassManager.h"
+#include "llvm/CodeGen/FreeMachineFunction.h"
+#include "llvm/CodeGen/FunctionToMachineFunctionAnalysis.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineModuleInfo.h"
#include "llvm/IR/PassManagerImpl.h"
@@ -69,9 +71,34 @@ bool MachineFunctionAnalysisManagerModuleProxy::Result::invalidate(
return false;
}
+template <>
+bool MachineFunctionAnalysisManagerFunctionProxy::Result::invalidate(
+ Function &F, const PreservedAnalyses &PA,
+ FunctionAnalysisManager::Invalidator &Inv) {
+ // If literally everything is preserved, we're done.
+ if (PA.areAllPreserved())
+ return false; // This is still a valid proxy.
+
+ // If this proxy isn't marked as preserved, then even if the result remains
+ // valid, the key itself may no longer be valid, so we clear everything.
+ //
+ // Once function changed by a non-trivial pass, we need to do instruction
+ // selection again.
+ auto PAC = PA.getChecker<MachineFunctionAnalysisManagerFunctionProxy>();
+ if (!PAC.preserved() && !PAC.preservedSet<AllAnalysesOn<Function>>()) {
+ InnerAM->clear();
+ return true;
+ }
+
+ // Return false to indicate that this result is still a valid proxy.
+ return false;
+}
+
PreservedAnalyses
ModuleToMachineFunctionPassAdaptor::run(Module &M, ModuleAnalysisManager &AM) {
- auto &MMI = AM.getResult<MachineModuleAnalysis>(M).getMMI();
+ // Ensure we have a MachineModuleInfo
+ AM.getResult<MachineModuleAnalysis>(M).getMMI();
+ auto &FAM = AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
MachineFunctionAnalysisManager &MFAM =
AM.getResult<MachineFunctionAnalysisManagerModuleProxy>(M).getManager();
PassInstrumentation PI = AM.getResult<PassInstrumentationAnalysis>(M);
@@ -82,19 +109,51 @@ ModuleToMachineFunctionPassAdaptor::run(Module &M, ModuleAnalysisManager &AM) {
if (F.isDeclaration() || F.hasAvailableExternallyLinkage())
continue;
- MachineFunction &MF = MMI.getOrCreateMachineFunction(F);
+ MachineFunction &MF =
+ FAM.getResult<FunctionToMachineFunctionAnalysis>(F).getMF();
if (!PI.runBeforePass<MachineFunction>(*Pass, MF))
continue;
PreservedAnalyses PassPA = Pass->run(MF, MFAM);
- if (MMI.getMachineFunction(F)) {
- MFAM.invalidate(MF, PassPA);
+ MFAM.invalidate(MF, PassPA);
+ if (Pass->name() != FreeMachineFunctionPass::name()) {
PI.runAfterPass(*Pass, MF, PassPA);
+ PA.intersect(std::move(PassPA));
} else {
- MFAM.clear(MF, F.getName());
- PI.runAfterPassInvalidated<MachineFunction>(*Pass, PassPA);
+ PA.intersect(std::move(PassPA));
+ FAM.invalidate(F, PA);
+ PI.runAfterPassInvalidated<MachineFunction>(*Pass, PA);
}
+ }
+
+ return PA;
+}
+
+PreservedAnalyses
+FunctionToMachineFunctionPassAdaptor::run(Function &F,
+ FunctionAnalysisManager &FAM) {
+ // Do not codegen any 'available_externally' functions at all, they have
+ // definitions outside the translation unit.
+ if (F.isDeclaration() || F.hasAvailableExternallyLinkage())
+ return PreservedAnalyses::all();
+
+ auto &MF = FAM.getResult<FunctionToMachineFunctionAnalysis>(F).getMF();
+ auto &MFAM = FAM.getResult<MachineFunctionAnalysisManagerFunctionProxy>(F)
+ .getManager();
+ auto PI = FAM.getResult<PassInstrumentationAnalysis>(F);
+ PreservedAnalyses PA = PreservedAnalyses::all();
+
+ if (!PI.runBeforePass<MachineFunction>(*Pass, MF))
+ return PreservedAnalyses::all();
+ PreservedAnalyses PassPA = Pass->run(MF, MFAM);
+ MFAM.invalidate(MF, PassPA);
+ if (Pass->name() != FreeMachineFunctionPass::name()) {
+ PI.runAfterPass(*Pass, MF, PassPA);
+ PA.intersect(std::move(PassPA));
+ } else {
PA.intersect(std::move(PassPA));
+ FAM.invalidate(F, PA);
+ PI.runAfterPassInvalidated<MachineFunction>(*Pass, PA);
}
return PA;
@@ -112,25 +171,24 @@ PreservedAnalyses
PassManager<MachineFunction>::run(MachineFunction &MF,
AnalysisManager<MachineFunction> &MFAM) {
PassInstrumentation PI = MFAM.getResult<PassInstrumentationAnalysis>(MF);
- Function &F = MF.getFunction();
- MachineModuleInfo &MMI =
- MFAM.getResult<ModuleAnalysisManagerMachineFunctionProxy>(MF)
- .getCachedResult<MachineModuleAnalysis>(*F.getParent())
- ->getMMI();
+ FunctionAnalysisManager &FAM =
+ MFAM.getResult<FunctionAnalysisManagerMachineFunctionProxy>(MF)
+ .getManager();
PreservedAnalyses PA = PreservedAnalyses::all();
for (auto &Pass : Passes) {
if (!PI.runBeforePass<MachineFunction>(*Pass, MF))
continue;
PreservedAnalyses PassPA = Pass->run(MF, MFAM);
- if (MMI.getMachineFunction(F)) {
- MFAM.invalidate(MF, PassPA);
+ MFAM.invalidate(MF, PassPA);
+ if (Pass->name() != FreeMachineFunctionPass::name()) {
PI.runAfterPass(*Pass, MF, PassPA);
+ PA.intersect(std::move(PassPA));
} else {
- MFAM.clear(MF, F.getName());
- PI.runAfterPassInvalidated<MachineFunction>(*Pass, PassPA);
+ PA.intersect(std::move(PassPA));
+ FAM.invalidate(MF.getFunction(), PA);
+ PI.runAfterPassInvalidated<MachineFunction>(*Pass, PA);
}
- PA.intersect(std::move(PassPA));
}
return PA;
}
diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index 8d408ca2363a98..0ffe5e8d60edfb 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -83,6 +83,7 @@
#include "llvm/CodeGen/ExpandLargeFpConvert.h"
#include "llvm/CodeGen/ExpandMemCmp.h"
#include "llvm/CodeGen/FreeMachineFunction.h"
+#include "llvm/CodeGen/FunctionToMachineFunctionAnalysis.h"
#include "llvm/CodeGen/GCMetadata.h"
#include "llvm/CodeGen/GlobalMerge.h"
#include "llvm/CodeGen/HardwareLoops.h"
diff --git a/llvm/unittests/CodeGen/PassManagerTest.cpp b/llvm/unittests/CodeGen/PassManagerTest.cpp
index 4283eb01a9c8f2..370fa558a511b6 100644
--- a/llvm/unittests/CodeGen/PassManagerTest.cpp
+++ b/llvm/unittests/CodeGen/PassManagerTest.cpp
@@ -176,10 +176,10 @@ TEST_F(PassManagerTest, Basic) {
MachineModuleInfo MMI(LLVMTM);
LoopAnalysisManager LAM;
+ MachineFunctionAnalysisManager MFAM;
FunctionAnalysisManager FAM;
CGSCCAnalysisManager CGAM;
ModuleAnalysisManager MAM;
- MachineFunctionAnalysisManager MFAM;
PassBuilder PB(TM.get());
PB.registerModuleAnalyses(MAM);
PB.registerCGSCCAnalyses(CGAM);
@@ -203,11 +203,15 @@ TEST_F(PassManagerTest, Basic) {
MPM.addPass(TestMachineModulePass(Count, Counts));
MFPM.addPass(TestMachineFunctionPass(Count, Counts));
MPM.addPass(createModuleToMachineFunctionPassAdaptor(std::move(MFPM)));
+ MPM.addPass(createModuleToFunctionPassAdaptor(
+ createFunctionToMachineFunctionPassAdaptor(
+ TestMachineFunctionPass(Count, Counts))));
MPM.run(*M, MAM);
- EXPECT_EQ((std::vector<int>{10, 16, 18, 20, 30, 36, 38, 40}), Counts);
- EXPECT_EQ(40, Count);
+ EXPECT_EQ((std::vector<int>{10, 16, 18, 20, 30, 36, 38, 40, 46, 48, 50}),
+ Counts);
+ EXPECT_EQ(50, Count);
}
} // namespace
More information about the llvm-commits
mailing list