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/FreeMachineFunction.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/CodeGenPassBuilder.h" // TODO: Include pass headers properly.
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"
48
49namespace llvm {
50extern cl::opt<bool> PrintPipelinePasses;
51} // namespace llvm
52
53using namespace llvm;
54
55static cl::opt<std::string>
56 RegAlloc("regalloc-npm",
57 cl::desc("Register allocator to use for new pass manager"),
58 cl::Hidden, cl::init(Val: "default"));
59
60static cl::opt<bool>
61 DebugPM("debug-pass-manager", cl::Hidden,
62 cl::desc("Print pass management debugging information"));
63
64bool LLCDiagnosticHandler::handleDiagnostics(const DiagnosticInfo &DI) {
65 DiagnosticHandler::handleDiagnostics(DI);
66 if (DI.getKind() == llvm::DK_SrcMgr) {
67 const auto &DISM = cast<DiagnosticInfoSrcMgr>(Val: DI);
68 const SMDiagnostic &SMD = DISM.getSMDiag();
69
70 SMD.print(ProgName: nullptr, S&: errs());
71
72 // For testing purposes, we print the LocCookie here.
73 if (DISM.isInlineAsmDiag() && DISM.getLocCookie())
74 WithColor::note() << "!srcloc = " << DISM.getLocCookie() << "\n";
75
76 return true;
77 }
78
79 if (auto *Remark = dyn_cast<DiagnosticInfoOptimizationBase>(Val: &DI))
80 if (!Remark->isEnabled())
81 return true;
82
83 DiagnosticPrinterRawOStream DP(errs());
84 errs() << LLVMContext::getDiagnosticMessagePrefix(Severity: DI.getSeverity()) << ": ";
85 DI.print(DP);
86 errs() << "\n";
87 return true;
88}
89
90static llvm::ExitOnError ExitOnErr;
91
92int llvm::compileModuleWithNewPM(
93 StringRef Arg0, std::unique_ptr<Module> M, std::unique_ptr<MIRParser> MIR,
94 std::unique_ptr<TargetMachine> Target, std::unique_ptr<ToolOutputFile> Out,
95 std::unique_ptr<ToolOutputFile> DwoOut, LLVMContext &Context,
96 const TargetLibraryInfoImpl &TLII, bool NoVerify, StringRef PassPipeline,
97 CodeGenFileType FileType) {
98
99 if (!PassPipeline.empty() && TargetPassConfig::hasLimitedCodeGenPipeline()) {
100 WithColor::warning(OS&: errs(), Prefix: Arg0)
101 << "--passes cannot be used with "
102 << TargetPassConfig::getLimitedCodeGenPipelineReason() << ".\n";
103 return 1;
104 }
105
106 LLVMTargetMachine &LLVMTM = static_cast<LLVMTargetMachine &>(*Target);
107
108 raw_pwrite_stream *OS = &Out->os();
109
110 // Fetch options from TargetPassConfig
111 CGPassBuilderOption Opt = getCGPassBuilderOption();
112 Opt.DisableVerify = NoVerify;
113 Opt.DebugPM = DebugPM;
114 Opt.RegAlloc = RegAlloc;
115
116 MachineModuleInfo MMI(&LLVMTM);
117
118 PassInstrumentationCallbacks PIC;
119 StandardInstrumentations SI(Context, Opt.DebugPM);
120 SI.registerCallbacks(PIC);
121 registerCodeGenCallback(PIC, LLVMTM);
122
123 LoopAnalysisManager LAM;
124 FunctionAnalysisManager FAM;
125 CGSCCAnalysisManager CGAM;
126 ModuleAnalysisManager MAM;
127 MachineFunctionAnalysisManager MFAM;
128 PassBuilder PB(Target.get(), PipelineTuningOptions(), std::nullopt, &PIC);
129 PB.registerModuleAnalyses(MAM);
130 PB.registerCGSCCAnalyses(CGAM);
131 PB.registerFunctionAnalyses(FAM);
132 PB.registerLoopAnalyses(LAM);
133 PB.registerMachineFunctionAnalyses(MFAM);
134 PB.crossRegisterProxies(LAM, FAM, CGAM, MAM, MFAM: &MFAM);
135
136 FAM.registerPass(PassBuilder: [&] { return TargetLibraryAnalysis(TLII); });
137 MAM.registerPass(PassBuilder: [&] { return MachineModuleAnalysis(MMI); });
138
139 ModulePassManager MPM;
140
141 if (!PassPipeline.empty()) {
142 // Construct a custom pass pipeline that starts after instruction
143 // selection.
144
145 if (!MIR) {
146 WithColor::warning(OS&: errs(), Prefix: 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, PipelineText: PassPipeline));
152 MPM.addPass(Pass: PrintMIRPreparePass(*OS));
153 MachineFunctionPassManager MFPM;
154 MFPM.addPass(Pass: PrintMIRPass(*OS));
155 MFPM.addPass(Pass: FreeMachineFunctionPass());
156 MPM.addPass(Pass: createModuleToMachineFunctionPassAdaptor(Pass: std::move(MFPM)));
157
158 if (MIR->parseMachineFunctions(M&: *M, MMI))
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, MapClassName2PassName: [&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(IR&: *M, AM&: MAM);
180
181 if (Context.getDiagHandlerPtr()->HasErrors)
182 exit(status: 1);
183
184 // Declare success.
185 Out->keep();
186 if (DwoOut)
187 DwoOut->keep();
188
189 return 0;
190}
191

source code of llvm/tools/llc/NewPMDriver.cpp