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"
15e8d8bef9SDimitry Andric #include "llvm/CodeGen/MachineModuleInfo.h"
16e8d8bef9SDimitry Andric #include "llvm/IR/PassManagerImpl.h"
17e8d8bef9SDimitry Andric 
18e8d8bef9SDimitry Andric using namespace llvm;
19e8d8bef9SDimitry Andric 
20e8d8bef9SDimitry Andric namespace llvm {
21e8d8bef9SDimitry Andric template class AllAnalysesOn<MachineFunction>;
22e8d8bef9SDimitry Andric template class AnalysisManager<MachineFunction>;
23e8d8bef9SDimitry Andric template class PassManager<MachineFunction>;
24e8d8bef9SDimitry Andric 
run(Module & M,MachineFunctionAnalysisManager & MFAM)25e8d8bef9SDimitry Andric Error MachineFunctionPassManager::run(Module &M,
26e8d8bef9SDimitry Andric                                       MachineFunctionAnalysisManager &MFAM) {
27e8d8bef9SDimitry Andric   // MachineModuleAnalysis is a module analysis pass that is never invalidated
28e8d8bef9SDimitry Andric   // because we don't run any module pass in codegen pipeline. This is very
29e8d8bef9SDimitry Andric   // important because the codegen state is stored in MMI which is the analysis
30e8d8bef9SDimitry Andric   // result of MachineModuleAnalysis. MMI should not be recomputed.
31e8d8bef9SDimitry Andric   auto &MMI = MFAM.getResult<MachineModuleAnalysis>(M);
32e8d8bef9SDimitry Andric 
33e8d8bef9SDimitry Andric   (void)RequireCodeGenSCCOrder;
34e8d8bef9SDimitry Andric   assert(!RequireCodeGenSCCOrder && "not implemented");
35e8d8bef9SDimitry Andric 
36*c9157d92SDimitry Andric   // M is unused here
37e8d8bef9SDimitry Andric   PassInstrumentation PI = MFAM.getResult<PassInstrumentationAnalysis>(M);
38e8d8bef9SDimitry Andric 
39*c9157d92SDimitry Andric   // Add a PIC to verify machine functions.
40*c9157d92SDimitry Andric   if (VerifyMachineFunction) {
41e8d8bef9SDimitry Andric     // No need to pop this callback later since MIR pipeline is flat which means
42e8d8bef9SDimitry Andric     // current pipeline is the top-level pipeline. Callbacks are not used after
43e8d8bef9SDimitry Andric     // current pipeline.
44e8d8bef9SDimitry Andric     PI.pushBeforeNonSkippedPassCallback([&MFAM](StringRef PassID, Any IR) {
45*c9157d92SDimitry Andric       assert(llvm::any_cast<const MachineFunction *>(&IR));
46*c9157d92SDimitry Andric       const MachineFunction *MF = llvm::any_cast<const MachineFunction *>(IR);
47e8d8bef9SDimitry Andric       assert(MF && "Machine function should be valid for printing");
48e8d8bef9SDimitry Andric       std::string Banner = std::string("After ") + std::string(PassID);
49e8d8bef9SDimitry Andric       verifyMachineFunction(&MFAM, Banner, *MF);
50e8d8bef9SDimitry Andric     });
51e8d8bef9SDimitry Andric   }
52e8d8bef9SDimitry Andric 
53e8d8bef9SDimitry Andric   for (auto &F : InitializationFuncs) {
54e8d8bef9SDimitry Andric     if (auto Err = F(M, MFAM))
55e8d8bef9SDimitry Andric       return Err;
56e8d8bef9SDimitry Andric   }
57e8d8bef9SDimitry Andric 
58e8d8bef9SDimitry Andric   unsigned Idx = 0;
59e8d8bef9SDimitry Andric   size_t Size = Passes.size();
60e8d8bef9SDimitry Andric   do {
61e8d8bef9SDimitry Andric     // Run machine module passes
62e8d8bef9SDimitry Andric     for (; MachineModulePasses.count(Idx) && Idx != Size; ++Idx) {
63*c9157d92SDimitry Andric       if (!PI.runBeforePass<Module>(*Passes[Idx], M))
64*c9157d92SDimitry Andric         continue;
65e8d8bef9SDimitry Andric       if (auto Err = MachineModulePasses.at(Idx)(M, MFAM))
66e8d8bef9SDimitry Andric         return Err;
67*c9157d92SDimitry Andric       PI.runAfterPass(*Passes[Idx], M, PreservedAnalyses::all());
68e8d8bef9SDimitry Andric     }
69e8d8bef9SDimitry Andric 
70e8d8bef9SDimitry Andric     // Finish running all passes.
71e8d8bef9SDimitry Andric     if (Idx == Size)
72e8d8bef9SDimitry Andric       break;
73e8d8bef9SDimitry Andric 
74e8d8bef9SDimitry Andric     // Run machine function passes
75e8d8bef9SDimitry Andric 
76e8d8bef9SDimitry Andric     // Get index range of machine function passes.
77e8d8bef9SDimitry Andric     unsigned Begin = Idx;
78e8d8bef9SDimitry Andric     for (; !MachineModulePasses.count(Idx) && Idx != Size; ++Idx)
79e8d8bef9SDimitry Andric       ;
80e8d8bef9SDimitry Andric 
81e8d8bef9SDimitry Andric     for (Function &F : M) {
82e8d8bef9SDimitry Andric       // Do not codegen any 'available_externally' functions at all, they have
83e8d8bef9SDimitry Andric       // definitions outside the translation unit.
84e8d8bef9SDimitry Andric       if (F.hasAvailableExternallyLinkage())
85e8d8bef9SDimitry Andric         continue;
86e8d8bef9SDimitry Andric 
87e8d8bef9SDimitry Andric       MachineFunction &MF = MMI.getOrCreateMachineFunction(F);
88e8d8bef9SDimitry Andric 
89e8d8bef9SDimitry Andric       for (unsigned I = Begin, E = Idx; I != E; ++I) {
90e8d8bef9SDimitry Andric         auto *P = Passes[I].get();
91e8d8bef9SDimitry Andric 
92e8d8bef9SDimitry Andric         if (!PI.runBeforePass<MachineFunction>(*P, MF))
93e8d8bef9SDimitry Andric           continue;
94e8d8bef9SDimitry Andric 
95e8d8bef9SDimitry Andric         // TODO: EmitSizeRemarks
96e8d8bef9SDimitry Andric         PreservedAnalyses PassPA = P->run(MF, MFAM);
97e8d8bef9SDimitry Andric         MFAM.invalidate(MF, PassPA);
98fe013be4SDimitry Andric         PI.runAfterPass(*P, MF, PassPA);
99e8d8bef9SDimitry Andric       }
100e8d8bef9SDimitry Andric     }
101e8d8bef9SDimitry Andric   } while (true);
102e8d8bef9SDimitry Andric 
103e8d8bef9SDimitry Andric   for (auto &F : FinalizationFuncs) {
104e8d8bef9SDimitry Andric     if (auto Err = F(M, MFAM))
105e8d8bef9SDimitry Andric       return Err;
106e8d8bef9SDimitry Andric   }
107e8d8bef9SDimitry Andric 
108e8d8bef9SDimitry Andric   return Error::success();
109e8d8bef9SDimitry Andric }
110e8d8bef9SDimitry Andric 
111e8d8bef9SDimitry Andric } // namespace llvm
112