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/CommandFlags.h"
19 #include "llvm/CodeGen/MIRParser/MIRParser.h"
20 #include "llvm/CodeGen/MIRPrinter.h"
21 #include "llvm/CodeGen/MachineFunctionAnalysis.h"
22 #include "llvm/CodeGen/MachineModuleInfo.h"
23 #include "llvm/CodeGen/MachinePassManager.h"
24 #include "llvm/CodeGen/MachineVerifier.h"
25 #include "llvm/CodeGen/TargetPassConfig.h"
26 #include "llvm/IR/DiagnosticInfo.h"
27 #include "llvm/IR/DiagnosticPrinter.h"
28 #include "llvm/IR/IRPrintingPasses.h"
29 #include "llvm/IR/LLVMContext.h"
30 #include "llvm/IR/Module.h"
31 #include "llvm/IR/PassManager.h"
32 #include "llvm/IR/Verifier.h"
33 #include "llvm/IRReader/IRReader.h"
34 #include "llvm/Passes/PassBuilder.h"
35 #include "llvm/Passes/StandardInstrumentations.h"
36 #include "llvm/Support/CommandLine.h"
37 #include "llvm/Support/Debug.h"
38 #include "llvm/Support/Error.h"
39 #include "llvm/Support/ErrorHandling.h"
40 #include "llvm/Support/FormattedStream.h"
41 #include "llvm/Support/ToolOutputFile.h"
42 #include "llvm/Support/WithColor.h"
43 #include "llvm/Target/CGPassBuilderOption.h"
44 #include "llvm/Target/TargetMachine.h"
45 #include "llvm/Target/TargetOptions.h"
46 #include "llvm/Transforms/Scalar/LoopPassManager.h"
47 #include "llvm/Transforms/Utils/Cloning.h"
51 static cl::opt
<std::string
>
52 RegAlloc("regalloc-npm",
53 cl::desc("Register allocator to use for new pass manager"),
54 cl::Hidden
, cl::init("default"));
57 DebugPM("debug-pass-manager", cl::Hidden
,
58 cl::desc("Print pass management debugging information"));
60 bool LLCDiagnosticHandler::handleDiagnostics(const DiagnosticInfo
&DI
) {
61 DiagnosticHandler::handleDiagnostics(DI
);
62 if (DI
.getKind() == llvm::DK_SrcMgr
) {
63 const auto &DISM
= cast
<DiagnosticInfoSrcMgr
>(DI
);
64 const SMDiagnostic
&SMD
= DISM
.getSMDiag();
66 SMD
.print(nullptr, errs());
68 // For testing purposes, we print the LocCookie here.
69 if (DISM
.isInlineAsmDiag() && DISM
.getLocCookie())
70 WithColor::note() << "!srcloc = " << DISM
.getLocCookie() << "\n";
75 if (auto *Remark
= dyn_cast
<DiagnosticInfoOptimizationBase
>(&DI
))
76 if (!Remark
->isEnabled())
79 DiagnosticPrinterRawOStream
DP(errs());
80 errs() << LLVMContext::getDiagnosticMessagePrefix(DI
.getSeverity()) << ": ";
86 static llvm::ExitOnError ExitOnErr
;
88 int llvm::compileModuleWithNewPM(
89 StringRef Arg0
, std::unique_ptr
<Module
> M
, std::unique_ptr
<MIRParser
> MIR
,
90 std::unique_ptr
<TargetMachine
> Target
, std::unique_ptr
<ToolOutputFile
> Out
,
91 std::unique_ptr
<ToolOutputFile
> DwoOut
, LLVMContext
&Context
,
92 const TargetLibraryInfoImpl
&TLII
, VerifierKind VK
, StringRef PassPipeline
,
93 CodeGenFileType FileType
) {
95 if (!PassPipeline
.empty() && TargetPassConfig::hasLimitedCodeGenPipeline()) {
96 WithColor::warning(errs(), Arg0
)
97 << "--passes cannot be used with "
98 << TargetPassConfig::getLimitedCodeGenPipelineReason() << ".\n";
102 raw_pwrite_stream
*OS
= &Out
->os();
104 // Fetch options from TargetPassConfig
105 CGPassBuilderOption Opt
= getCGPassBuilderOption();
106 Opt
.DisableVerify
= VK
!= VerifierKind::InputOutput
;
107 Opt
.DebugPM
= DebugPM
;
108 Opt
.RegAlloc
= RegAlloc
;
110 MachineModuleInfo
MMI(Target
.get());
112 PassInstrumentationCallbacks PIC
;
113 StandardInstrumentations
SI(Context
, Opt
.DebugPM
,
114 VK
== VerifierKind::EachPass
);
115 registerCodeGenCallback(PIC
, *Target
);
117 MachineFunctionAnalysisManager MFAM
;
118 LoopAnalysisManager LAM
;
119 FunctionAnalysisManager FAM
;
120 CGSCCAnalysisManager CGAM
;
121 ModuleAnalysisManager MAM
;
122 PassBuilder
PB(Target
.get(), PipelineTuningOptions(), std::nullopt
, &PIC
);
123 PB
.registerModuleAnalyses(MAM
);
124 PB
.registerCGSCCAnalyses(CGAM
);
125 PB
.registerFunctionAnalyses(FAM
);
126 PB
.registerLoopAnalyses(LAM
);
127 PB
.registerMachineFunctionAnalyses(MFAM
);
128 PB
.crossRegisterProxies(LAM
, FAM
, CGAM
, MAM
, &MFAM
);
129 SI
.registerCallbacks(PIC
, &MAM
);
131 FAM
.registerPass([&] { return TargetLibraryAnalysis(TLII
); });
132 MAM
.registerPass([&] { return MachineModuleAnalysis(MMI
); });
134 ModulePassManager MPM
;
135 FunctionPassManager FPM
;
137 if (!PassPipeline
.empty()) {
138 // Construct a custom pass pipeline that starts after instruction
142 WithColor::warning(errs(), Arg0
) << "-passes is for .mir file only.\n";
146 // FIXME: verify that there are no IR passes.
147 ExitOnErr(PB
.parsePassPipeline(MPM
, PassPipeline
));
148 MPM
.addPass(PrintMIRPreparePass(*OS
));
149 MachineFunctionPassManager MFPM
;
150 if (VK
== VerifierKind::InputOutput
)
151 MFPM
.addPass(MachineVerifierPass());
152 MFPM
.addPass(PrintMIRPass(*OS
));
153 FPM
.addPass(createFunctionToMachineFunctionPassAdaptor(std::move(MFPM
)));
154 MPM
.addPass(createModuleToFunctionPassAdaptor(std::move(FPM
)));
156 if (MIR
->parseMachineFunctions(*M
, MAM
))
159 ExitOnErr(Target
->buildCodeGenPipeline(
160 MPM
, *OS
, DwoOut
? &DwoOut
->os() : nullptr, FileType
, Opt
, &PIC
));
163 if (PrintPipelinePasses
) {
164 std::string PipelineStr
;
165 raw_string_ostream
OS(PipelineStr
);
166 MPM
.printPipeline(OS
, [&PIC
](StringRef ClassName
) {
167 auto PassName
= PIC
.getPassNameForClassName(ClassName
);
168 return PassName
.empty() ? ClassName
: PassName
;
170 outs() << PipelineStr
<< '\n';
174 // Before executing passes, print the final values of the LLVM options.
175 cl::PrintOptionValues();
179 if (Context
.getDiagHandlerPtr()->HasErrors
)