Skip to content

Commit e666834

Browse files
committed
[NewPM] Introduce MFAnalysisGetter for a common analysis getter
1 parent be67756 commit e666834

File tree

1 file changed

+78
-0
lines changed

1 file changed

+78
-0
lines changed

llvm/include/llvm/CodeGen/MachinePassManager.h

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,10 @@
2424
#include "llvm/ADT/FunctionExtras.h"
2525
#include "llvm/ADT/SmallVector.h"
2626
#include "llvm/CodeGen/MachineFunction.h"
27+
#include "llvm/IR/Function.h"
2728
#include "llvm/IR/PassManager.h"
2829
#include "llvm/IR/PassManagerInternal.h"
30+
#include "llvm/Pass.h"
2931
#include "llvm/Support/Error.h"
3032

3133
namespace llvm {
@@ -236,6 +238,82 @@ using MachineFunctionPassManager = PassManager<MachineFunction>;
236238
/// preserve.
237239
PreservedAnalyses getMachineFunctionPassPreservedAnalyses();
238240

241+
/// For migrating to new pass manager
242+
/// Provides a common interface to fetch analyses instead of doing it twice in
243+
/// the *LegacyPass::runOnMachineFunction and NPM Pass::run.
244+
///
245+
/// NPM analyses must have the LegacyWrapper type to indicate which legacy
246+
/// analysis to run. Legacy wrapper analyses must have `getResult()` method.
247+
/// This can be added on a needs-to basis.
248+
///
249+
/// Outer analyses passes(Module or Function) can also be requested through
250+
/// `getAnalysis` or `getCachedAnalysis`.
251+
class MFAnalysisGetter {
252+
private:
253+
Pass *LegacyPass;
254+
MachineFunctionAnalysisManager *MFAM;
255+
256+
template <typename T>
257+
using type_of_run =
258+
typename function_traits<decltype(&T::run)>::template arg_t<0>;
259+
260+
template <typename T>
261+
static constexpr bool IsFunctionAnalysis =
262+
std::is_same_v<Function, type_of_run<T>>;
263+
264+
template <typename T>
265+
static constexpr bool IsModuleAnalysis =
266+
std::is_same_v<Module, type_of_run<T>>;
267+
268+
public:
269+
MFAnalysisGetter(Pass *LegacyPass) : LegacyPass(LegacyPass) {}
270+
MFAnalysisGetter(MachineFunctionAnalysisManager *MFAM) : MFAM(MFAM) {}
271+
272+
/// Outer analyses requested from NPM will be cached results and can be null
273+
template <typename AnalysisT>
274+
typename AnalysisT::Result *getAnalysis(MachineFunction &MF) {
275+
if (MFAM) {
276+
// need a proxy to get the result for outer analyses
277+
// this can return null
278+
if constexpr (IsModuleAnalysis<AnalysisT>)
279+
return MFAM->getResult<ModuleAnalysisManagerMachineFunctionProxy>(MF)
280+
.getCachedResult<AnalysisT>(*MF.getFunction().getParent());
281+
else if constexpr (IsFunctionAnalysis<AnalysisT>) {
282+
return &MFAM->getResult<FunctionAnalysisManagerMachineFunctionProxy>(MF)
283+
.getManager()
284+
.getResult<AnalysisT>(MF.getFunction());
285+
}
286+
return &MFAM->getResult<AnalysisT>(MF);
287+
}
288+
return &LegacyPass->getAnalysis<typename AnalysisT::LegacyWrapper>()
289+
.getResult();
290+
}
291+
292+
template <typename AnalysisT>
293+
typename AnalysisT::Result *getCachedAnalysis(MachineFunction &MF) {
294+
if (MFAM) {
295+
if constexpr (IsFunctionAnalysis<AnalysisT>) {
296+
return MFAM->getResult<FunctionAnalysisManagerMachineFunctionProxy>(MF)
297+
.getManager()
298+
.getCachedResult<AnalysisT>(MF.getFunction());
299+
} else if constexpr (IsModuleAnalysis<AnalysisT>)
300+
return MFAM->getResult<ModuleAnalysisManagerMachineFunctionProxy>(MF)
301+
.getCachedResult<AnalysisT>(*MF.getFunction().getParent());
302+
303+
return &MFAM->getCachedResult<AnalysisT>(MF);
304+
}
305+
306+
if (auto *P =
307+
LegacyPass->getAnalysisIfAvailable<AnalysisT::LegacyWrapper>())
308+
return &P->getResult();
309+
return nullptr;
310+
}
311+
312+
/// This is not intended to be used to invoke getAnalysis()
313+
Pass *getLegacyPass() const { return LegacyPass; }
314+
MachineFunctionAnalysisManager *getMFAM() const { return MFAM; }
315+
};
316+
239317
} // end namespace llvm
240318

241319
#endif // LLVM_CODEGEN_MACHINEPASSMANAGER_H

0 commit comments

Comments
 (0)