170 lines · cpp
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-exception6//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 22using namespace llvm;23 24AnalysisKey FunctionAnalysisManagerMachineFunctionProxy::Key;25 26namespace llvm {27template class LLVM_EXPORT_TEMPLATE AnalysisManager<MachineFunction>;28template class PassManager<MachineFunction>;29template class LLVM_EXPORT_TEMPLATE30 InnerAnalysisManagerProxy<MachineFunctionAnalysisManager, Module>;31template class LLVM_EXPORT_TEMPLATE32 InnerAnalysisManagerProxy<MachineFunctionAnalysisManager, Function>;33template class LLVM_EXPORT_TEMPLATE34 OuterAnalysisManagerProxy<ModuleAnalysisManager, MachineFunction>;35} // namespace llvm36 37bool 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 45template <>46bool 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 remains54 // 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 that57 // the MFAM has been completely updated to handle the deletion of functions.58 // Specifically, any MFAM-cached results for those functions need to have been59 // forcibly cleared. When preserved, this proxy will only invalidate results60 // 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, see68 // 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 78template <>79bool 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 remains87 // 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 that90 // the MFAM has been completely updated to handle the deletion of functions.91 // Specifically, any MFAM-cached results for those functions need to have been92 // forcibly cleared. When preserved, this proxy will only invalidate results93 // 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, see101 // 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 111PreservedAnalyses112FunctionToMachineFunctionPassAdaptor::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 have120 // 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 136void FunctionToMachineFunctionPassAdaptor::printPipeline(137 raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {138 OS << "machine-function(";139 Pass->printPipeline(OS, MapClassName2PassName);140 OS << ')';141}142 143template <>144PreservedAnalyses145PassManager<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 162PreservedAnalyses llvm::getMachineFunctionPassPreservedAnalyses() {163 PreservedAnalyses PA;164 // Machine function passes are not allowed to modify the LLVM165 // 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