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/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"
48
49 using namespace llvm;
50
51 static cl::opt<RegAllocType, false, RegAllocTypeParser>
52 RegAlloc("regalloc-npm",
53 cl::desc("Register allocator to use for new pass manager"),
54 cl::Hidden, cl::init(RegAllocType::Unset));
55
56 static cl::opt<bool>
57 DebugPM("debug-pass-manager", cl::Hidden,
58 cl::desc("Print pass management debugging information"));
59
handleDiagnostics(const DiagnosticInfo & DI)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();
65
66 SMD.print(nullptr, errs());
67
68 // For testing purposes, we print the LocCookie here.
69 if (DISM.isInlineAsmDiag() && DISM.getLocCookie())
70 WithColor::note() << "!srcloc = " << DISM.getLocCookie() << "\n";
71
72 return true;
73 }
74
75 if (auto *Remark = dyn_cast<DiagnosticInfoOptimizationBase>(&DI))
76 if (!Remark->isEnabled())
77 return true;
78
79 DiagnosticPrinterRawOStream DP(errs());
80 errs() << LLVMContext::getDiagnosticMessagePrefix(DI.getSeverity()) << ": ";
81 DI.print(DP);
82 errs() << "\n";
83 return true;
84 }
85
86 static llvm::ExitOnError ExitOnErr;
87
compileModuleWithNewPM(StringRef Arg0,std::unique_ptr<Module> M,std::unique_ptr<MIRParser> MIR,std::unique_ptr<TargetMachine> Target,std::unique_ptr<ToolOutputFile> Out,std::unique_ptr<ToolOutputFile> DwoOut,LLVMContext & Context,const TargetLibraryInfoImpl & TLII,VerifierKind VK,StringRef PassPipeline,CodeGenFileType FileType)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) {
94
95 if (!PassPipeline.empty() && TargetPassConfig::hasLimitedCodeGenPipeline()) {
96 WithColor::error(errs(), Arg0)
97 << "--passes cannot be used with "
98 << TargetPassConfig::getLimitedCodeGenPipelineReason() << ".\n";
99 return 1;
100 }
101
102 raw_pwrite_stream *OS = &Out->os();
103
104 // Fetch options from TargetPassConfig
105 CGPassBuilderOption Opt = getCGPassBuilderOption();
106 Opt.DisableVerify = VK != VerifierKind::InputOutput;
107 Opt.DebugPM = DebugPM;
108 Opt.RegAlloc = RegAlloc;
109
110 MachineModuleInfo MMI(Target.get());
111
112 PassInstrumentationCallbacks PIC;
113 StandardInstrumentations SI(Context, Opt.DebugPM,
114 VK == VerifierKind::EachPass);
115 registerCodeGenCallback(PIC, *Target);
116
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);
130
131 FAM.registerPass([&] { return TargetLibraryAnalysis(TLII); });
132 MAM.registerPass([&] { return MachineModuleAnalysis(MMI); });
133
134 ModulePassManager MPM;
135 FunctionPassManager FPM;
136
137 if (!PassPipeline.empty()) {
138 // Construct a custom pass pipeline that starts after instruction
139 // selection.
140
141 if (!MIR) {
142 WithColor::error(errs(), Arg0) << "-passes is for .mir file only.\n";
143 return 1;
144 }
145
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)));
155
156 } else {
157 ExitOnErr(Target->buildCodeGenPipeline(
158 MPM, *OS, DwoOut ? &DwoOut->os() : nullptr, FileType, Opt, &PIC));
159 }
160
161 // If user only wants to print the pipeline, print it before parsing the MIR.
162 if (PrintPipelinePasses) {
163 std::string PipelineStr;
164 raw_string_ostream OS(PipelineStr);
165 MPM.printPipeline(OS, [&PIC](StringRef ClassName) {
166 auto PassName = PIC.getPassNameForClassName(ClassName);
167 return PassName.empty() ? ClassName : PassName;
168 });
169 outs() << PipelineStr << '\n';
170 return 0;
171 }
172
173 if (MIR && MIR->parseMachineFunctions(*M, MAM))
174 return 1;
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