1e8d8bef9SDimitry Andric //===---------- MachinePassManager.cpp ------------------------------------===// 2e8d8bef9SDimitry Andric // 3e8d8bef9SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4e8d8bef9SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5e8d8bef9SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6e8d8bef9SDimitry Andric // 7e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===// 8e8d8bef9SDimitry Andric // 9e8d8bef9SDimitry Andric // This file contains the pass management machinery for machine functions. 10e8d8bef9SDimitry Andric // 11e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===// 12e8d8bef9SDimitry Andric 13e8d8bef9SDimitry Andric #include "llvm/CodeGen/MachinePassManager.h" 14e8d8bef9SDimitry Andric #include "llvm/CodeGen/MachineFunction.h" 15*0fca6ea1SDimitry Andric #include "llvm/CodeGen/MachineFunctionAnalysis.h" 16e8d8bef9SDimitry Andric #include "llvm/CodeGen/MachineModuleInfo.h" 17e8d8bef9SDimitry Andric #include "llvm/IR/PassManagerImpl.h" 18e8d8bef9SDimitry Andric 19e8d8bef9SDimitry Andric using namespace llvm; 20e8d8bef9SDimitry Andric 21*0fca6ea1SDimitry Andric AnalysisKey FunctionAnalysisManagerMachineFunctionProxy::Key; 22*0fca6ea1SDimitry Andric 23e8d8bef9SDimitry Andric namespace llvm { 24e8d8bef9SDimitry Andric template class AnalysisManager<MachineFunction>; 25e8d8bef9SDimitry Andric template class PassManager<MachineFunction>; 26*0fca6ea1SDimitry Andric template class InnerAnalysisManagerProxy<MachineFunctionAnalysisManager, 27*0fca6ea1SDimitry Andric Module>; 28*0fca6ea1SDimitry Andric template class InnerAnalysisManagerProxy<MachineFunctionAnalysisManager, 29*0fca6ea1SDimitry Andric Function>; 30*0fca6ea1SDimitry Andric template class OuterAnalysisManagerProxy<ModuleAnalysisManager, 31*0fca6ea1SDimitry Andric MachineFunction>; 32*0fca6ea1SDimitry Andric } // namespace llvm 33e8d8bef9SDimitry Andric 34*0fca6ea1SDimitry Andric bool FunctionAnalysisManagerMachineFunctionProxy::Result::invalidate( 35*0fca6ea1SDimitry Andric MachineFunction &IR, const PreservedAnalyses &PA, 36*0fca6ea1SDimitry Andric MachineFunctionAnalysisManager::Invalidator &Inv) { 37*0fca6ea1SDimitry Andric // MachineFunction passes should not invalidate Function analyses. 38*0fca6ea1SDimitry Andric // TODO: verify that PA doesn't invalidate Function analyses. 39*0fca6ea1SDimitry Andric return false; 40e8d8bef9SDimitry Andric } 41e8d8bef9SDimitry Andric 42*0fca6ea1SDimitry Andric template <> 43*0fca6ea1SDimitry Andric bool MachineFunctionAnalysisManagerModuleProxy::Result::invalidate( 44*0fca6ea1SDimitry Andric Module &M, const PreservedAnalyses &PA, 45*0fca6ea1SDimitry Andric ModuleAnalysisManager::Invalidator &Inv) { 46*0fca6ea1SDimitry Andric // If literally everything is preserved, we're done. 47*0fca6ea1SDimitry Andric if (PA.areAllPreserved()) 48*0fca6ea1SDimitry Andric return false; // This is still a valid proxy. 49*0fca6ea1SDimitry Andric 50*0fca6ea1SDimitry Andric // If this proxy isn't marked as preserved, then even if the result remains 51*0fca6ea1SDimitry Andric // valid, the key itself may no longer be valid, so we clear everything. 52*0fca6ea1SDimitry Andric // 53*0fca6ea1SDimitry Andric // Note that in order to preserve this proxy, a module pass must ensure that 54*0fca6ea1SDimitry Andric // the MFAM has been completely updated to handle the deletion of functions. 55*0fca6ea1SDimitry Andric // Specifically, any MFAM-cached results for those functions need to have been 56*0fca6ea1SDimitry Andric // forcibly cleared. When preserved, this proxy will only invalidate results 57*0fca6ea1SDimitry Andric // cached on functions *still in the module* at the end of the module pass. 58*0fca6ea1SDimitry Andric auto PAC = PA.getChecker<MachineFunctionAnalysisManagerModuleProxy>(); 59*0fca6ea1SDimitry Andric if (!PAC.preserved() && !PAC.preservedSet<AllAnalysesOn<Module>>()) { 60*0fca6ea1SDimitry Andric InnerAM->clear(); 61*0fca6ea1SDimitry Andric return true; 62e8d8bef9SDimitry Andric } 63e8d8bef9SDimitry Andric 64*0fca6ea1SDimitry Andric // FIXME: be more precise, see 65*0fca6ea1SDimitry Andric // FunctionAnalysisManagerModuleProxy::Result::invalidate. 66*0fca6ea1SDimitry Andric if (!PA.allAnalysesInSetPreserved<AllAnalysesOn<MachineFunction>>()) { 67*0fca6ea1SDimitry Andric InnerAM->clear(); 68*0fca6ea1SDimitry Andric return true; 69e8d8bef9SDimitry Andric } 70e8d8bef9SDimitry Andric 71*0fca6ea1SDimitry Andric // Return false to indicate that this result is still a valid proxy. 72*0fca6ea1SDimitry Andric return false; 73*0fca6ea1SDimitry Andric } 74e8d8bef9SDimitry Andric 75*0fca6ea1SDimitry Andric template <> 76*0fca6ea1SDimitry Andric bool MachineFunctionAnalysisManagerFunctionProxy::Result::invalidate( 77*0fca6ea1SDimitry Andric Function &F, const PreservedAnalyses &PA, 78*0fca6ea1SDimitry Andric FunctionAnalysisManager::Invalidator &Inv) { 79*0fca6ea1SDimitry Andric // If literally everything is preserved, we're done. 80*0fca6ea1SDimitry Andric if (PA.areAllPreserved()) 81*0fca6ea1SDimitry Andric return false; // This is still a valid proxy. 82e8d8bef9SDimitry Andric 83*0fca6ea1SDimitry Andric // If this proxy isn't marked as preserved, then even if the result remains 84*0fca6ea1SDimitry Andric // valid, the key itself may no longer be valid, so we clear everything. 85*0fca6ea1SDimitry Andric // 86*0fca6ea1SDimitry Andric // Note that in order to preserve this proxy, a module pass must ensure that 87*0fca6ea1SDimitry Andric // the MFAM has been completely updated to handle the deletion of functions. 88*0fca6ea1SDimitry Andric // Specifically, any MFAM-cached results for those functions need to have been 89*0fca6ea1SDimitry Andric // forcibly cleared. When preserved, this proxy will only invalidate results 90*0fca6ea1SDimitry Andric // cached on functions *still in the module* at the end of the module pass. 91*0fca6ea1SDimitry Andric auto PAC = PA.getChecker<MachineFunctionAnalysisManagerFunctionProxy>(); 92*0fca6ea1SDimitry Andric if (!PAC.preserved() && !PAC.preservedSet<AllAnalysesOn<Function>>()) { 93*0fca6ea1SDimitry Andric InnerAM->clear(); 94*0fca6ea1SDimitry Andric return true; 95*0fca6ea1SDimitry Andric } 96e8d8bef9SDimitry Andric 97*0fca6ea1SDimitry Andric // FIXME: be more precise, see 98*0fca6ea1SDimitry Andric // FunctionAnalysisManagerModuleProxy::Result::invalidate. 99*0fca6ea1SDimitry Andric if (!PA.allAnalysesInSetPreserved<AllAnalysesOn<MachineFunction>>()) { 100*0fca6ea1SDimitry Andric InnerAM->clear(); 101*0fca6ea1SDimitry Andric return true; 102*0fca6ea1SDimitry Andric } 103*0fca6ea1SDimitry Andric 104*0fca6ea1SDimitry Andric // Return false to indicate that this result is still a valid proxy. 105*0fca6ea1SDimitry Andric return false; 106*0fca6ea1SDimitry Andric } 107*0fca6ea1SDimitry Andric 108*0fca6ea1SDimitry Andric PreservedAnalyses 109*0fca6ea1SDimitry Andric FunctionToMachineFunctionPassAdaptor::run(Function &F, 110*0fca6ea1SDimitry Andric FunctionAnalysisManager &FAM) { 111*0fca6ea1SDimitry Andric MachineFunctionAnalysisManager &MFAM = 112*0fca6ea1SDimitry Andric FAM.getResult<MachineFunctionAnalysisManagerFunctionProxy>(F) 113*0fca6ea1SDimitry Andric .getManager(); 114*0fca6ea1SDimitry Andric PassInstrumentation PI = FAM.getResult<PassInstrumentationAnalysis>(F); 115*0fca6ea1SDimitry Andric PreservedAnalyses PA = PreservedAnalyses::all(); 116e8d8bef9SDimitry Andric // Do not codegen any 'available_externally' functions at all, they have 117e8d8bef9SDimitry Andric // definitions outside the translation unit. 118*0fca6ea1SDimitry Andric if (F.isDeclaration() || F.hasAvailableExternallyLinkage()) 119*0fca6ea1SDimitry Andric return PreservedAnalyses::all(); 120e8d8bef9SDimitry Andric 121*0fca6ea1SDimitry Andric MachineFunction &MF = FAM.getResult<MachineFunctionAnalysis>(F).getMF(); 122e8d8bef9SDimitry Andric 123*0fca6ea1SDimitry Andric if (!PI.runBeforePass<MachineFunction>(*Pass, MF)) 124*0fca6ea1SDimitry Andric return PreservedAnalyses::all(); 125*0fca6ea1SDimitry Andric PreservedAnalyses PassPA = Pass->run(MF, MFAM); 126e8d8bef9SDimitry Andric MFAM.invalidate(MF, PassPA); 127*0fca6ea1SDimitry Andric PI.runAfterPass(*Pass, MF, PassPA); 128*0fca6ea1SDimitry Andric PA.intersect(std::move(PassPA)); 129e8d8bef9SDimitry Andric 130*0fca6ea1SDimitry Andric return PA; 131e8d8bef9SDimitry Andric } 132e8d8bef9SDimitry Andric 133*0fca6ea1SDimitry Andric void FunctionToMachineFunctionPassAdaptor::printPipeline( 134*0fca6ea1SDimitry Andric raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) { 135*0fca6ea1SDimitry Andric OS << "machine-function("; 136*0fca6ea1SDimitry Andric Pass->printPipeline(OS, MapClassName2PassName); 137*0fca6ea1SDimitry Andric OS << ')'; 138e8d8bef9SDimitry Andric } 139e8d8bef9SDimitry Andric 140*0fca6ea1SDimitry Andric template <> 141*0fca6ea1SDimitry Andric PreservedAnalyses 142*0fca6ea1SDimitry Andric PassManager<MachineFunction>::run(MachineFunction &MF, 143*0fca6ea1SDimitry Andric AnalysisManager<MachineFunction> &MFAM) { 144*0fca6ea1SDimitry Andric PassInstrumentation PI = MFAM.getResult<PassInstrumentationAnalysis>(MF); 145*0fca6ea1SDimitry Andric PreservedAnalyses PA = PreservedAnalyses::all(); 146*0fca6ea1SDimitry Andric for (auto &Pass : Passes) { 147*0fca6ea1SDimitry Andric if (!PI.runBeforePass<MachineFunction>(*Pass, MF)) 148*0fca6ea1SDimitry Andric continue; 149*0fca6ea1SDimitry Andric 150*0fca6ea1SDimitry Andric PreservedAnalyses PassPA = Pass->run(MF, MFAM); 151*0fca6ea1SDimitry Andric MFAM.invalidate(MF, PassPA); 152*0fca6ea1SDimitry Andric PI.runAfterPass(*Pass, MF, PassPA); 153*0fca6ea1SDimitry Andric PA.intersect(std::move(PassPA)); 154*0fca6ea1SDimitry Andric } 155*0fca6ea1SDimitry Andric return PA; 156*0fca6ea1SDimitry Andric } 157*0fca6ea1SDimitry Andric 158*0fca6ea1SDimitry Andric PreservedAnalyses llvm::getMachineFunctionPassPreservedAnalyses() { 159*0fca6ea1SDimitry Andric PreservedAnalyses PA; 160*0fca6ea1SDimitry Andric // Machine function passes are not allowed to modify the LLVM 161*0fca6ea1SDimitry Andric // representation, therefore we should preserve all IR analyses. 162*0fca6ea1SDimitry Andric PA.template preserveSet<AllAnalysesOn<Module>>(); 163*0fca6ea1SDimitry Andric PA.template preserveSet<AllAnalysesOn<Function>>(); 164*0fca6ea1SDimitry Andric return PA; 165*0fca6ea1SDimitry Andric } 166