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