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