Skip to content

[NewPM] Add FunctionToMachineFunctionPassAdaptor #88711

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

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 33 additions & 12 deletions llvm/include/llvm/CodeGen/MachinePassManager.h
Original file line number Diff line number Diff line change
Expand Up @@ -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();
}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This causes destruction issue when destruct analysis managers.


Result &operator=(Result &&RHS) {
FAM = RHS.FAM;
// We have to null out the analysis manager in the moved-from state
Expand Down Expand Up @@ -211,15 +201,46 @@ 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(
std::unique_ptr<ModuleToMachineFunctionPassAdaptor::PassConceptT>(
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) {
Expand Down
90 changes: 74 additions & 16 deletions llvm/lib/CodeGen/MachinePassManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this something that actually happens? I thought once we're done with codegen, we're basically done with the IR as well

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This never happened, MachineOutliner just only create dummy IR functions to get associated machine functions.

// 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);
Expand All @@ -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;
Expand All @@ -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;
}
Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Passes/PassBuilder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
10 changes: 7 additions & 3 deletions llvm/unittests/CodeGen/PassManagerTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand All @@ -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