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