xref: /freebsd/contrib/llvm-project/llvm/tools/llc/NewPMDriver.cpp (revision b64c5a0ace59af62eff52bfe110a521dc73c937b)
1 //===- NewPMDriver.cpp - Driver for llc using 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 llc.cpp but
11 /// that includes the new pass manager headers.
12 ///
13 //===----------------------------------------------------------------------===//
14 
15 #include "NewPMDriver.h"
16 #include "llvm/Analysis/CGSCCPassManager.h"
17 #include "llvm/Analysis/TargetLibraryInfo.h"
18 #include "llvm/CodeGen/CommandFlags.h"
19 #include "llvm/CodeGen/MIRParser/MIRParser.h"
20 #include "llvm/CodeGen/MIRPrinter.h"
21 #include "llvm/CodeGen/MachineModuleInfo.h"
22 #include "llvm/CodeGen/MachinePassManager.h"
23 #include "llvm/CodeGen/TargetPassConfig.h"
24 #include "llvm/IR/DiagnosticInfo.h"
25 #include "llvm/IR/DiagnosticPrinter.h"
26 #include "llvm/IR/IRPrintingPasses.h"
27 #include "llvm/IR/LLVMContext.h"
28 #include "llvm/IR/Module.h"
29 #include "llvm/IR/PassManager.h"
30 #include "llvm/IR/Verifier.h"
31 #include "llvm/IRReader/IRReader.h"
32 #include "llvm/Passes/CodeGenPassBuilder.h" // TODO: Include pass headers properly.
33 #include "llvm/Passes/PassBuilder.h"
34 #include "llvm/Passes/StandardInstrumentations.h"
35 #include "llvm/Support/CommandLine.h"
36 #include "llvm/Support/Debug.h"
37 #include "llvm/Support/Error.h"
38 #include "llvm/Support/ErrorHandling.h"
39 #include "llvm/Support/FormattedStream.h"
40 #include "llvm/Support/ToolOutputFile.h"
41 #include "llvm/Support/WithColor.h"
42 #include "llvm/Target/CGPassBuilderOption.h"
43 #include "llvm/Target/TargetMachine.h"
44 #include "llvm/Target/TargetOptions.h"
45 #include "llvm/Transforms/Scalar/LoopPassManager.h"
46 #include "llvm/Transforms/Utils/Cloning.h"
47 
48 namespace llvm {
49 extern cl::opt<bool> PrintPipelinePasses;
50 } // namespace llvm
51 
52 using namespace llvm;
53 
54 static cl::opt<std::string>
55     RegAlloc("regalloc-npm",
56              cl::desc("Register allocator to use for new pass manager"),
57              cl::Hidden, cl::init("default"));
58 
59 static cl::opt<bool>
60     DebugPM("debug-pass-manager", cl::Hidden,
61             cl::desc("Print pass management debugging information"));
62 
63 bool LLCDiagnosticHandler::handleDiagnostics(const DiagnosticInfo &DI) {
64   DiagnosticHandler::handleDiagnostics(DI);
65   if (DI.getKind() == llvm::DK_SrcMgr) {
66     const auto &DISM = cast<DiagnosticInfoSrcMgr>(DI);
67     const SMDiagnostic &SMD = DISM.getSMDiag();
68 
69     SMD.print(nullptr, errs());
70 
71     // For testing purposes, we print the LocCookie here.
72     if (DISM.isInlineAsmDiag() && DISM.getLocCookie())
73       WithColor::note() << "!srcloc = " << DISM.getLocCookie() << "\n";
74 
75     return true;
76   }
77 
78   if (auto *Remark = dyn_cast<DiagnosticInfoOptimizationBase>(&DI))
79     if (!Remark->isEnabled())
80       return true;
81 
82   DiagnosticPrinterRawOStream DP(errs());
83   errs() << LLVMContext::getDiagnosticMessagePrefix(DI.getSeverity()) << ": ";
84   DI.print(DP);
85   errs() << "\n";
86   return true;
87 }
88 
89 static llvm::ExitOnError ExitOnErr;
90 
91 int llvm::compileModuleWithNewPM(
92     StringRef Arg0, std::unique_ptr<Module> M, std::unique_ptr<MIRParser> MIR,
93     std::unique_ptr<TargetMachine> Target, std::unique_ptr<ToolOutputFile> Out,
94     std::unique_ptr<ToolOutputFile> DwoOut, LLVMContext &Context,
95     const TargetLibraryInfoImpl &TLII, bool NoVerify, StringRef PassPipeline,
96     CodeGenFileType FileType) {
97 
98   if (!PassPipeline.empty() && TargetPassConfig::hasLimitedCodeGenPipeline()) {
99     WithColor::warning(errs(), Arg0)
100         << "--passes cannot be used with "
101         << TargetPassConfig::getLimitedCodeGenPipelineReason() << ".\n";
102     return 1;
103   }
104 
105   LLVMTargetMachine &LLVMTM = static_cast<LLVMTargetMachine &>(*Target);
106 
107   raw_pwrite_stream *OS = &Out->os();
108 
109   // Fetch options from TargetPassConfig
110   CGPassBuilderOption Opt = getCGPassBuilderOption();
111   Opt.DisableVerify = NoVerify;
112   Opt.DebugPM = DebugPM;
113   Opt.RegAlloc = RegAlloc;
114 
115   MachineModuleInfo MMI(&LLVMTM);
116 
117   PassInstrumentationCallbacks PIC;
118   StandardInstrumentations SI(Context, Opt.DebugPM, !NoVerify);
119   registerCodeGenCallback(PIC, LLVMTM);
120 
121   MachineFunctionAnalysisManager MFAM;
122   LoopAnalysisManager LAM;
123   FunctionAnalysisManager FAM;
124   CGSCCAnalysisManager CGAM;
125   ModuleAnalysisManager MAM;
126   PassBuilder PB(Target.get(), PipelineTuningOptions(), std::nullopt, &PIC);
127   PB.registerModuleAnalyses(MAM);
128   PB.registerCGSCCAnalyses(CGAM);
129   PB.registerFunctionAnalyses(FAM);
130   PB.registerLoopAnalyses(LAM);
131   PB.registerMachineFunctionAnalyses(MFAM);
132   PB.crossRegisterProxies(LAM, FAM, CGAM, MAM, &MFAM);
133   SI.registerCallbacks(PIC, &MAM);
134 
135   FAM.registerPass([&] { return TargetLibraryAnalysis(TLII); });
136   MAM.registerPass([&] { return MachineModuleAnalysis(MMI); });
137 
138   ModulePassManager MPM;
139   FunctionPassManager FPM;
140 
141   if (!PassPipeline.empty()) {
142     // Construct a custom pass pipeline that starts after instruction
143     // selection.
144 
145     if (!MIR) {
146       WithColor::warning(errs(), Arg0) << "-passes is for .mir file only.\n";
147       return 1;
148     }
149 
150     // FIXME: verify that there are no IR passes.
151     ExitOnErr(PB.parsePassPipeline(MPM, PassPipeline));
152     MPM.addPass(PrintMIRPreparePass(*OS));
153     MachineFunctionPassManager MFPM;
154     MFPM.addPass(PrintMIRPass(*OS));
155     FPM.addPass(createFunctionToMachineFunctionPassAdaptor(std::move(MFPM)));
156     MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));
157 
158     if (MIR->parseMachineFunctions(*M, MAM))
159       return 1;
160   } else {
161     ExitOnErr(LLVMTM.buildCodeGenPipeline(
162         MPM, *OS, DwoOut ? &DwoOut->os() : nullptr, FileType, Opt, &PIC));
163   }
164 
165   if (PrintPipelinePasses) {
166     std::string PipelineStr;
167     raw_string_ostream OS(PipelineStr);
168     MPM.printPipeline(OS, [&PIC](StringRef ClassName) {
169       auto PassName = PIC.getPassNameForClassName(ClassName);
170       return PassName.empty() ? ClassName : PassName;
171     });
172     outs() << PipelineStr << '\n';
173     return 0;
174   }
175 
176   // Before executing passes, print the final values of the LLVM options.
177   cl::PrintOptionValues();
178 
179   MPM.run(*M, MAM);
180 
181   if (Context.getDiagHandlerPtr()->HasErrors)
182     exit(1);
183 
184   // Declare success.
185   Out->keep();
186   if (DwoOut)
187     DwoOut->keep();
188 
189   return 0;
190 }
191