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