]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/llvm/tools/opt/NewPMDriver.cpp
MFC r355940:
[FreeBSD/FreeBSD.git] / contrib / llvm-project / llvm / tools / opt / NewPMDriver.cpp
1 //===- NewPMDriver.cpp - Driver for opt with new PM -----------------------===//
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-exception
6 //
7 //===----------------------------------------------------------------------===//
8 /// \file
9 ///
10 /// This file is just a split of the code that logically belongs in opt.cpp but
11 /// that includes the new pass manager headers.
12 ///
13 //===----------------------------------------------------------------------===//
14
15 #include "NewPMDriver.h"
16 #include "Debugify.h"
17 #include "PassPrinters.h"
18 #include "llvm/ADT/StringRef.h"
19 #include "llvm/Analysis/AliasAnalysis.h"
20 #include "llvm/Analysis/CGSCCPassManager.h"
21 #include "llvm/Bitcode/BitcodeWriterPass.h"
22 #include "llvm/Config/llvm-config.h"
23 #include "llvm/IR/Dominators.h"
24 #include "llvm/IR/IRPrintingPasses.h"
25 #include "llvm/IR/LLVMContext.h"
26 #include "llvm/IR/Module.h"
27 #include "llvm/IR/PassManager.h"
28 #include "llvm/IR/Verifier.h"
29 #include "llvm/Passes/PassBuilder.h"
30 #include "llvm/Passes/PassPlugin.h"
31 #include "llvm/Passes/StandardInstrumentations.h"
32 #include "llvm/Support/CommandLine.h"
33 #include "llvm/Support/ErrorHandling.h"
34 #include "llvm/Support/ToolOutputFile.h"
35 #include "llvm/Target/TargetMachine.h"
36 #include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
37 #include "llvm/Transforms/Scalar/LoopPassManager.h"
38
39 using namespace llvm;
40 using namespace opt_tool;
41
42 static cl::opt<bool>
43     DebugPM("debug-pass-manager", cl::Hidden,
44             cl::desc("Print pass management debugging information"));
45
46 static cl::list<std::string>
47     PassPlugins("load-pass-plugin",
48                 cl::desc("Load passes from plugin library"));
49
50 // This flag specifies a textual description of the alias analysis pipeline to
51 // use when querying for aliasing information. It only works in concert with
52 // the "passes" flag above.
53 static cl::opt<std::string>
54     AAPipeline("aa-pipeline",
55                cl::desc("A textual description of the alias analysis "
56                         "pipeline for handling managed aliasing queries"),
57                cl::Hidden);
58
59 /// {{@ These options accept textual pipeline descriptions which will be
60 /// inserted into default pipelines at the respective extension points
61 static cl::opt<std::string> PeepholeEPPipeline(
62     "passes-ep-peephole",
63     cl::desc("A textual description of the function pass pipeline inserted at "
64              "the Peephole extension points into default pipelines"),
65     cl::Hidden);
66 static cl::opt<std::string> LateLoopOptimizationsEPPipeline(
67     "passes-ep-late-loop-optimizations",
68     cl::desc(
69         "A textual description of the loop pass pipeline inserted at "
70         "the LateLoopOptimizations extension point into default pipelines"),
71     cl::Hidden);
72 static cl::opt<std::string> LoopOptimizerEndEPPipeline(
73     "passes-ep-loop-optimizer-end",
74     cl::desc("A textual description of the loop pass pipeline inserted at "
75              "the LoopOptimizerEnd extension point into default pipelines"),
76     cl::Hidden);
77 static cl::opt<std::string> ScalarOptimizerLateEPPipeline(
78     "passes-ep-scalar-optimizer-late",
79     cl::desc("A textual description of the function pass pipeline inserted at "
80              "the ScalarOptimizerLate extension point into default pipelines"),
81     cl::Hidden);
82 static cl::opt<std::string> CGSCCOptimizerLateEPPipeline(
83     "passes-ep-cgscc-optimizer-late",
84     cl::desc("A textual description of the cgscc pass pipeline inserted at "
85              "the CGSCCOptimizerLate extension point into default pipelines"),
86     cl::Hidden);
87 static cl::opt<std::string> VectorizerStartEPPipeline(
88     "passes-ep-vectorizer-start",
89     cl::desc("A textual description of the function pass pipeline inserted at "
90              "the VectorizerStart extension point into default pipelines"),
91     cl::Hidden);
92 static cl::opt<std::string> PipelineStartEPPipeline(
93     "passes-ep-pipeline-start",
94     cl::desc("A textual description of the function pass pipeline inserted at "
95              "the PipelineStart extension point into default pipelines"),
96     cl::Hidden);
97 static cl::opt<std::string> OptimizerLastEPPipeline(
98     "passes-ep-optimizer-last",
99     cl::desc("A textual description of the function pass pipeline inserted at "
100              "the OptimizerLast extension point into default pipelines"),
101     cl::Hidden);
102
103 extern cl::opt<PGOKind> PGOKindFlag;
104 extern cl::opt<std::string> ProfileFile;
105 extern cl::opt<CSPGOKind> CSPGOKindFlag;
106 extern cl::opt<std::string> CSProfileGenFile;
107
108 static cl::opt<std::string>
109     ProfileRemappingFile("profile-remapping-file",
110                          cl::desc("Path to the profile remapping file."),
111                          cl::Hidden);
112 static cl::opt<bool> DebugInfoForProfiling(
113     "new-pm-debug-info-for-profiling", cl::init(false), cl::Hidden,
114     cl::desc("Emit special debug info to enable PGO profile generation."));
115 /// @}}
116
117 template <typename PassManagerT>
118 bool tryParsePipelineText(PassBuilder &PB,
119                           const cl::opt<std::string> &PipelineOpt) {
120   if (PipelineOpt.empty())
121     return false;
122
123   // Verify the pipeline is parseable:
124   PassManagerT PM;
125   if (auto Err = PB.parsePassPipeline(PM, PipelineOpt)) {
126     errs() << "Could not parse -" << PipelineOpt.ArgStr
127            << " pipeline: " << toString(std::move(Err))
128            << "... I'm going to ignore it.\n";
129     return false;
130   }
131   return true;
132 }
133
134 /// If one of the EPPipeline command line options was given, register callbacks
135 /// for parsing and inserting the given pipeline
136 static void registerEPCallbacks(PassBuilder &PB, bool VerifyEachPass,
137                                 bool DebugLogging) {
138   if (tryParsePipelineText<FunctionPassManager>(PB, PeepholeEPPipeline))
139     PB.registerPeepholeEPCallback(
140         [&PB, VerifyEachPass, DebugLogging](
141             FunctionPassManager &PM, PassBuilder::OptimizationLevel Level) {
142           ExitOnError Err("Unable to parse PeepholeEP pipeline: ");
143           Err(PB.parsePassPipeline(PM, PeepholeEPPipeline, VerifyEachPass,
144                                    DebugLogging));
145         });
146   if (tryParsePipelineText<LoopPassManager>(PB,
147                                             LateLoopOptimizationsEPPipeline))
148     PB.registerLateLoopOptimizationsEPCallback(
149         [&PB, VerifyEachPass, DebugLogging](
150             LoopPassManager &PM, PassBuilder::OptimizationLevel Level) {
151           ExitOnError Err("Unable to parse LateLoopOptimizationsEP pipeline: ");
152           Err(PB.parsePassPipeline(PM, LateLoopOptimizationsEPPipeline,
153                                    VerifyEachPass, DebugLogging));
154         });
155   if (tryParsePipelineText<LoopPassManager>(PB, LoopOptimizerEndEPPipeline))
156     PB.registerLoopOptimizerEndEPCallback(
157         [&PB, VerifyEachPass, DebugLogging](
158             LoopPassManager &PM, PassBuilder::OptimizationLevel Level) {
159           ExitOnError Err("Unable to parse LoopOptimizerEndEP pipeline: ");
160           Err(PB.parsePassPipeline(PM, LoopOptimizerEndEPPipeline,
161                                    VerifyEachPass, DebugLogging));
162         });
163   if (tryParsePipelineText<FunctionPassManager>(PB,
164                                                 ScalarOptimizerLateEPPipeline))
165     PB.registerScalarOptimizerLateEPCallback(
166         [&PB, VerifyEachPass, DebugLogging](
167             FunctionPassManager &PM, PassBuilder::OptimizationLevel Level) {
168           ExitOnError Err("Unable to parse ScalarOptimizerLateEP pipeline: ");
169           Err(PB.parsePassPipeline(PM, ScalarOptimizerLateEPPipeline,
170                                    VerifyEachPass, DebugLogging));
171         });
172   if (tryParsePipelineText<CGSCCPassManager>(PB, CGSCCOptimizerLateEPPipeline))
173     PB.registerCGSCCOptimizerLateEPCallback(
174         [&PB, VerifyEachPass, DebugLogging](
175             CGSCCPassManager &PM, PassBuilder::OptimizationLevel Level) {
176           ExitOnError Err("Unable to parse CGSCCOptimizerLateEP pipeline: ");
177           Err(PB.parsePassPipeline(PM, CGSCCOptimizerLateEPPipeline,
178                                    VerifyEachPass, DebugLogging));
179         });
180   if (tryParsePipelineText<FunctionPassManager>(PB, VectorizerStartEPPipeline))
181     PB.registerVectorizerStartEPCallback(
182         [&PB, VerifyEachPass, DebugLogging](
183             FunctionPassManager &PM, PassBuilder::OptimizationLevel Level) {
184           ExitOnError Err("Unable to parse VectorizerStartEP pipeline: ");
185           Err(PB.parsePassPipeline(PM, VectorizerStartEPPipeline,
186                                    VerifyEachPass, DebugLogging));
187         });
188   if (tryParsePipelineText<ModulePassManager>(PB, PipelineStartEPPipeline))
189     PB.registerPipelineStartEPCallback(
190         [&PB, VerifyEachPass, DebugLogging](ModulePassManager &PM) {
191           ExitOnError Err("Unable to parse PipelineStartEP pipeline: ");
192           Err(PB.parsePassPipeline(PM, PipelineStartEPPipeline, VerifyEachPass,
193                                    DebugLogging));
194         });
195   if (tryParsePipelineText<FunctionPassManager>(PB, OptimizerLastEPPipeline))
196     PB.registerOptimizerLastEPCallback(
197         [&PB, VerifyEachPass, DebugLogging](FunctionPassManager &PM,
198                                             PassBuilder::OptimizationLevel) {
199           ExitOnError Err("Unable to parse OptimizerLastEP pipeline: ");
200           Err(PB.parsePassPipeline(PM, OptimizerLastEPPipeline, VerifyEachPass,
201                                    DebugLogging));
202         });
203 }
204
205 #ifdef LINK_POLLY_INTO_TOOLS
206 namespace polly {
207 void RegisterPollyPasses(PassBuilder &);
208 }
209 #endif
210
211 bool llvm::runPassPipeline(StringRef Arg0, Module &M, TargetMachine *TM,
212                            ToolOutputFile *Out, ToolOutputFile *ThinLTOLinkOut,
213                            ToolOutputFile *OptRemarkFile,
214                            StringRef PassPipeline, OutputKind OK,
215                            VerifierKind VK,
216                            bool ShouldPreserveAssemblyUseListOrder,
217                            bool ShouldPreserveBitcodeUseListOrder,
218                            bool EmitSummaryIndex, bool EmitModuleHash,
219                            bool EnableDebugify) {
220   bool VerifyEachPass = VK == VK_VerifyEachPass;
221
222   Optional<PGOOptions> P;
223   switch (PGOKindFlag) {
224     case InstrGen:
225       P = PGOOptions(ProfileFile, "", "", PGOOptions::IRInstr);
226       break;
227     case InstrUse:
228       P = PGOOptions(ProfileFile, "", ProfileRemappingFile, PGOOptions::IRUse);
229       break;
230     case SampleUse:
231       P = PGOOptions(ProfileFile, "", ProfileRemappingFile,
232                      PGOOptions::SampleUse);
233       break;
234     case NoPGO:
235       if (DebugInfoForProfiling)
236         P = PGOOptions("", "", "", PGOOptions::NoAction, PGOOptions::NoCSAction,
237                        true);
238       else
239         P = None;
240     }
241     if (CSPGOKindFlag != NoCSPGO) {
242       if (P && (P->Action == PGOOptions::IRInstr ||
243                 P->Action == PGOOptions::SampleUse))
244         errs() << "CSPGOKind cannot be used with IRInstr or SampleUse";
245       if (CSPGOKindFlag == CSInstrGen) {
246         if (CSProfileGenFile.empty())
247           errs() << "CSInstrGen needs to specify CSProfileGenFile";
248         if (P) {
249           P->CSAction = PGOOptions::CSIRInstr;
250           P->CSProfileGenFile = CSProfileGenFile;
251         } else
252           P = PGOOptions("", CSProfileGenFile, ProfileRemappingFile,
253                          PGOOptions::NoAction, PGOOptions::CSIRInstr);
254       } else /* CSPGOKindFlag == CSInstrUse */ {
255         if (!P)
256           errs() << "CSInstrUse needs to be together with InstrUse";
257         P->CSAction = PGOOptions::CSIRUse;
258       }
259     }
260   PassInstrumentationCallbacks PIC;
261   StandardInstrumentations SI;
262   SI.registerCallbacks(PIC);
263
264   PassBuilder PB(TM, PipelineTuningOptions(), P, &PIC);
265   registerEPCallbacks(PB, VerifyEachPass, DebugPM);
266
267   // Load requested pass plugins and let them register pass builder callbacks
268   for (auto &PluginFN : PassPlugins) {
269     auto PassPlugin = PassPlugin::Load(PluginFN);
270     if (!PassPlugin) {
271       errs() << "Failed to load passes from '" << PluginFN
272              << "'. Request ignored.\n";
273       continue;
274     }
275
276     PassPlugin->registerPassBuilderCallbacks(PB);
277   }
278
279   // Register a callback that creates the debugify passes as needed.
280   PB.registerPipelineParsingCallback(
281       [](StringRef Name, ModulePassManager &MPM,
282          ArrayRef<PassBuilder::PipelineElement>) {
283         if (Name == "debugify") {
284           MPM.addPass(NewPMDebugifyPass());
285           return true;
286         } else if (Name == "check-debugify") {
287           MPM.addPass(NewPMCheckDebugifyPass());
288           return true;
289         }
290         return false;
291       });
292
293 #ifdef LINK_POLLY_INTO_TOOLS
294   polly::RegisterPollyPasses(PB);
295 #endif
296
297   // Specially handle the alias analysis manager so that we can register
298   // a custom pipeline of AA passes with it.
299   AAManager AA;
300   if (auto Err = PB.parseAAPipeline(AA, AAPipeline)) {
301     errs() << Arg0 << ": " << toString(std::move(Err)) << "\n";
302     return false;
303   }
304
305   LoopAnalysisManager LAM(DebugPM);
306   FunctionAnalysisManager FAM(DebugPM);
307   CGSCCAnalysisManager CGAM(DebugPM);
308   ModuleAnalysisManager MAM(DebugPM);
309
310   // Register the AA manager first so that our version is the one used.
311   FAM.registerPass([&] { return std::move(AA); });
312
313   // Register all the basic analyses with the managers.
314   PB.registerModuleAnalyses(MAM);
315   PB.registerCGSCCAnalyses(CGAM);
316   PB.registerFunctionAnalyses(FAM);
317   PB.registerLoopAnalyses(LAM);
318   PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
319
320   ModulePassManager MPM(DebugPM);
321   if (VK > VK_NoVerifier)
322     MPM.addPass(VerifierPass());
323   if (EnableDebugify)
324     MPM.addPass(NewPMDebugifyPass());
325
326   if (auto Err =
327           PB.parsePassPipeline(MPM, PassPipeline, VerifyEachPass, DebugPM)) {
328     errs() << Arg0 << ": " << toString(std::move(Err)) << "\n";
329     return false;
330   }
331
332   if (VK > VK_NoVerifier)
333     MPM.addPass(VerifierPass());
334   if (EnableDebugify)
335     MPM.addPass(NewPMCheckDebugifyPass());
336
337   // Add any relevant output pass at the end of the pipeline.
338   switch (OK) {
339   case OK_NoOutput:
340     break; // No output pass needed.
341   case OK_OutputAssembly:
342     MPM.addPass(
343         PrintModulePass(Out->os(), "", ShouldPreserveAssemblyUseListOrder));
344     break;
345   case OK_OutputBitcode:
346     MPM.addPass(BitcodeWriterPass(Out->os(), ShouldPreserveBitcodeUseListOrder,
347                                   EmitSummaryIndex, EmitModuleHash));
348     break;
349   case OK_OutputThinLTOBitcode:
350     MPM.addPass(ThinLTOBitcodeWriterPass(
351         Out->os(), ThinLTOLinkOut ? &ThinLTOLinkOut->os() : nullptr));
352     break;
353   }
354
355   // Before executing passes, print the final values of the LLVM options.
356   cl::PrintOptionValues();
357
358   // Now that we have all of the passes ready, run them.
359   MPM.run(M, MAM);
360
361   // Declare success.
362   if (OK != OK_NoOutput) {
363     Out->keep();
364     if (OK == OK_OutputThinLTOBitcode && ThinLTOLinkOut)
365       ThinLTOLinkOut->keep();
366   }
367
368   if (OptRemarkFile)
369     OptRemarkFile->keep();
370
371   return true;
372 }