[llvm-shlib] Fix the version naming style of libLLVM for Windows (#85710)
[llvm-project.git] / llvm / tools / llc / NewPMDriver.cpp
blob13020f3dd07feba7d39ef8053a1fd8a7af44d349
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 //===----------------------------------------------------------------------===//
15 #include "NewPMDriver.h"
16 #include "llvm/Analysis/CGSCCPassManager.h"
17 #include "llvm/Analysis/TargetLibraryInfo.h"
18 #include "llvm/CodeGen/CodeGenPassBuilder.h"
19 #include "llvm/CodeGen/CommandFlags.h"
20 #include "llvm/CodeGen/MIRParser/MIRParser.h"
21 #include "llvm/CodeGen/MIRPrinter.h"
22 #include "llvm/CodeGen/MachineModuleInfo.h"
23 #include "llvm/CodeGen/MachinePassManager.h"
24 #include "llvm/CodeGen/TargetPassConfig.h"
25 #include "llvm/IR/DiagnosticInfo.h"
26 #include "llvm/IR/DiagnosticPrinter.h"
27 #include "llvm/IR/IRPrintingPasses.h"
28 #include "llvm/IR/LLVMContext.h"
29 #include "llvm/IR/Module.h"
30 #include "llvm/IR/PassManager.h"
31 #include "llvm/IR/Verifier.h"
32 #include "llvm/IRReader/IRReader.h"
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"
48 namespace llvm {
49 extern cl::opt<bool> PrintPipelinePasses;
50 } // namespace llvm
52 using namespace llvm;
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"));
59 static cl::opt<bool>
60 DebugPM("debug-pass-manager", cl::Hidden,
61 cl::desc("Print pass management debugging information"));
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();
69 SMD.print(nullptr, errs());
71 // For testing purposes, we print the LocCookie here.
72 if (DISM.isInlineAsmDiag() && DISM.getLocCookie())
73 WithColor::note() << "!srcloc = " << DISM.getLocCookie() << "\n";
75 return true;
78 if (auto *Remark = dyn_cast<DiagnosticInfoOptimizationBase>(&DI))
79 if (!Remark->isEnabled())
80 return true;
82 DiagnosticPrinterRawOStream DP(errs());
83 errs() << LLVMContext::getDiagnosticMessagePrefix(DI.getSeverity()) << ": ";
84 DI.print(DP);
85 errs() << "\n";
86 return true;
89 static llvm::ExitOnError ExitOnErr;
91 static void RunPasses(bool BOS, ToolOutputFile *Out, Module *M,
92 LLVMContext &Context, SmallString<0> &Buffer,
93 ModulePassManager *MPM, ModuleAnalysisManager *MAM,
94 MachineFunctionPassManager &MFPM,
95 MachineFunctionAnalysisManager &MFAM) {
96 assert(M && "invalid input module!");
98 // Before executing passes, print the final values of the LLVM options.
99 cl::PrintOptionValues();
101 if (MPM) {
102 assert(MAM && "expect a ModuleAnalysisManager!");
103 MPM->run(*M, *MAM);
106 ExitOnErr(MFPM.run(*M, MFAM));
108 if (Context.getDiagHandlerPtr()->HasErrors)
109 exit(1);
111 if (BOS)
112 Out->os() << Buffer;
115 int llvm::compileModuleWithNewPM(
116 StringRef Arg0, std::unique_ptr<Module> M, std::unique_ptr<MIRParser> MIR,
117 std::unique_ptr<TargetMachine> Target, std::unique_ptr<ToolOutputFile> Out,
118 std::unique_ptr<ToolOutputFile> DwoOut, LLVMContext &Context,
119 const TargetLibraryInfoImpl &TLII, bool NoVerify, StringRef PassPipeline,
120 CodeGenFileType FileType) {
122 if (!PassPipeline.empty() && TargetPassConfig::hasLimitedCodeGenPipeline()) {
123 WithColor::warning(errs(), Arg0)
124 << "--passes cannot be used with "
125 << TargetPassConfig::getLimitedCodeGenPipelineReason() << ".\n";
126 return 1;
129 LLVMTargetMachine &LLVMTM = static_cast<LLVMTargetMachine &>(*Target);
131 raw_pwrite_stream *OS = &Out->os();
133 // Manually do the buffering rather than using buffer_ostream,
134 // so we can memcmp the contents in CompileTwice mode in future.
135 SmallString<0> Buffer;
136 std::unique_ptr<raw_svector_ostream> BOS;
137 if ((codegen::getFileType() != CodeGenFileType::AssemblyFile &&
138 !Out->os().supportsSeeking())) {
139 BOS = std::make_unique<raw_svector_ostream>(Buffer);
140 OS = BOS.get();
143 // Fetch options from TargetPassConfig
144 CGPassBuilderOption Opt = getCGPassBuilderOption();
145 Opt.DisableVerify = NoVerify;
146 Opt.DebugPM = DebugPM;
147 Opt.RegAlloc = RegAlloc;
149 PassInstrumentationCallbacks PIC;
150 StandardInstrumentations SI(Context, Opt.DebugPM);
151 SI.registerCallbacks(PIC);
152 registerCodeGenCallback(PIC, LLVMTM);
154 LoopAnalysisManager LAM;
155 FunctionAnalysisManager FAM;
156 CGSCCAnalysisManager CGAM;
157 ModuleAnalysisManager MAM;
158 PassBuilder PB(Target.get(), PipelineTuningOptions(), std::nullopt, &PIC);
159 PB.registerModuleAnalyses(MAM);
160 PB.registerCGSCCAnalyses(CGAM);
161 PB.registerFunctionAnalyses(FAM);
162 PB.registerLoopAnalyses(LAM);
163 PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
165 FAM.registerPass([&] { return TargetLibraryAnalysis(TLII); });
166 MAM.registerPass([&] { return MachineModuleAnalysis(&LLVMTM); });
168 MachineFunctionAnalysisManager MFAM(FAM, MAM);
170 if (!PassPipeline.empty()) {
171 // Construct a custom pass pipeline that starts after instruction
172 // selection.
174 if (!MIR) {
175 WithColor::warning(errs(), Arg0) << "-passes is for .mir file only.\n";
176 return 1;
179 MachineFunctionPassManager MFPM;
180 ExitOnErr(PB.parsePassPipeline(MFPM, PassPipeline));
181 MFPM.addPass(PrintMIRPass(*OS));
182 MFPM.addPass(FreeMachineFunctionPass());
184 auto &MMI = MFAM.getResult<MachineModuleAnalysis>(*M);
185 if (MIR->parseMachineFunctions(*M, MMI))
186 return 1;
188 RunPasses(BOS.get(), Out.get(), M.get(), Context, Buffer, nullptr, nullptr,
189 MFPM, MFAM);
190 } else {
191 ModulePassManager MPM;
192 MachineFunctionPassManager MFPM;
194 ExitOnErr(LLVMTM.buildCodeGenPipeline(MPM, MFPM, MFAM, *OS,
195 DwoOut ? &DwoOut->os() : nullptr,
196 FileType, Opt, &PIC));
198 auto StartStopInfo = TargetPassConfig::getStartStopInfo(PIC);
199 assert(StartStopInfo && "Expect StartStopInfo!");
200 // Add IR or MIR printing pass according the pass type.
202 if (auto StopPassName = StartStopInfo->StopPass; !StopPassName.empty()) {
203 MFPM.addPass(PrintMIRPass(*OS));
204 MFPM.addPass(FreeMachineFunctionPass());
207 if (PrintPipelinePasses) {
208 std::string IRPipeline;
209 raw_string_ostream IRSOS(IRPipeline);
210 MPM.printPipeline(IRSOS, [&PIC](StringRef ClassName) {
211 auto PassName = PIC.getPassNameForClassName(ClassName);
212 return PassName.empty() ? ClassName : PassName;
214 outs() << "IR pipeline: " << IRPipeline << '\n';
216 std::string MIRPipeline;
217 raw_string_ostream MIRSOS(MIRPipeline);
218 MFPM.printPipeline(MIRSOS, [&PIC](StringRef ClassName) {
219 auto PassName = PIC.getPassNameForClassName(ClassName);
220 return PassName.empty() ? ClassName : PassName;
222 outs() << "MIR pipeline: " << MIRPipeline << '\n';
223 return 0;
226 RunPasses(BOS.get(), Out.get(), M.get(), Context, Buffer, &MPM, &MAM, MFPM,
227 MFAM);
230 // Declare success.
231 Out->keep();
232 if (DwoOut)
233 DwoOut->keep();
235 return 0;