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<std::string> 52 RegAlloc("regalloc-npm", 53 cl::desc("Register allocator to use for new pass manager"), 54 cl::Hidden, cl::init("default")); 55 56 static cl::opt<bool> 57 DebugPM("debug-pass-manager", cl::Hidden, 58 cl::desc("Print pass management debugging information")); 59 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 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::warning(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::warning(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 if (MIR->parseMachineFunctions(*M, MAM)) 157 return 1; 158 } else { 159 ExitOnErr(Target->buildCodeGenPipeline( 160 MPM, *OS, DwoOut ? &DwoOut->os() : nullptr, FileType, Opt, &PIC)); 161 } 162 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; 169 }); 170 outs() << PipelineStr << '\n'; 171 return 0; 172 } 173 174 // Before executing passes, print the final values of the LLVM options. 175 cl::PrintOptionValues(); 176 177 MPM.run(*M, MAM); 178 179 if (Context.getDiagHandlerPtr()->HasErrors) 180 exit(1); 181 182 // Declare success. 183 Out->keep(); 184 if (DwoOut) 185 DwoOut->keep(); 186 187 return 0; 188 } 189