1 //===- NewPMDriver.cpp - Driver for llc using new PM ----------------------===//
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
7 //===----------------------------------------------------------------------===//
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.
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"
49 extern cl::opt
<bool> PrintPipelinePasses
;
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"));
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";
78 if (auto *Remark
= dyn_cast
<DiagnosticInfoOptimizationBase
>(&DI
))
79 if (!Remark
->isEnabled())
82 DiagnosticPrinterRawOStream
DP(errs());
83 errs() << LLVMContext::getDiagnosticMessagePrefix(DI
.getSeverity()) << ": ";
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();
102 assert(MAM
&& "expect a ModuleAnalysisManager!");
106 ExitOnErr(MFPM
.run(*M
, MFAM
));
108 if (Context
.getDiagHandlerPtr()->HasErrors
)
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";
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
);
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
175 WithColor::warning(errs(), Arg0
) << "-passes is for .mir file only.\n";
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
))
188 RunPasses(BOS
.get(), Out
.get(), M
.get(), Context
, Buffer
, nullptr, nullptr,
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';
226 RunPasses(BOS
.get(), Out
.get(), M
.get(), Context
, Buffer
, &MPM
, &MAM
, MFPM
,