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/MachineModuleInfo.h" 22 #include "llvm/CodeGen/MachinePassManager.h" 23 #include "llvm/CodeGen/TargetPassConfig.h" 24 #include "llvm/IR/DiagnosticInfo.h" 25 #include "llvm/IR/DiagnosticPrinter.h" 26 #include "llvm/IR/IRPrintingPasses.h" 27 #include "llvm/IR/LLVMContext.h" 28 #include "llvm/IR/Module.h" 29 #include "llvm/IR/PassManager.h" 30 #include "llvm/IR/Verifier.h" 31 #include "llvm/IRReader/IRReader.h" 32 #include "llvm/Passes/CodeGenPassBuilder.h" // TODO: Include pass headers properly. 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" 47 48 namespace llvm { 49 extern cl::opt<bool> PrintPipelinePasses; 50 } // namespace llvm 51 52 using namespace llvm; 53 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")); 58 59 static cl::opt<bool> 60 DebugPM("debug-pass-manager", cl::Hidden, 61 cl::desc("Print pass management debugging information")); 62 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(); 68 69 SMD.print(nullptr, errs()); 70 71 // For testing purposes, we print the LocCookie here. 72 if (DISM.isInlineAsmDiag() && DISM.getLocCookie()) 73 WithColor::note() << "!srcloc = " << DISM.getLocCookie() << "\n"; 74 75 return true; 76 } 77 78 if (auto *Remark = dyn_cast<DiagnosticInfoOptimizationBase>(&DI)) 79 if (!Remark->isEnabled()) 80 return true; 81 82 DiagnosticPrinterRawOStream DP(errs()); 83 errs() << LLVMContext::getDiagnosticMessagePrefix(DI.getSeverity()) << ": "; 84 DI.print(DP); 85 errs() << "\n"; 86 return true; 87 } 88 89 static llvm::ExitOnError ExitOnErr; 90 91 int llvm::compileModuleWithNewPM( 92 StringRef Arg0, std::unique_ptr<Module> M, std::unique_ptr<MIRParser> MIR, 93 std::unique_ptr<TargetMachine> Target, std::unique_ptr<ToolOutputFile> Out, 94 std::unique_ptr<ToolOutputFile> DwoOut, LLVMContext &Context, 95 const TargetLibraryInfoImpl &TLII, bool NoVerify, StringRef PassPipeline, 96 CodeGenFileType FileType) { 97 98 if (!PassPipeline.empty() && TargetPassConfig::hasLimitedCodeGenPipeline()) { 99 WithColor::warning(errs(), Arg0) 100 << "--passes cannot be used with " 101 << TargetPassConfig::getLimitedCodeGenPipelineReason() << ".\n"; 102 return 1; 103 } 104 105 LLVMTargetMachine &LLVMTM = static_cast<LLVMTargetMachine &>(*Target); 106 107 raw_pwrite_stream *OS = &Out->os(); 108 109 // Fetch options from TargetPassConfig 110 CGPassBuilderOption Opt = getCGPassBuilderOption(); 111 Opt.DisableVerify = NoVerify; 112 Opt.DebugPM = DebugPM; 113 Opt.RegAlloc = RegAlloc; 114 115 MachineModuleInfo MMI(&LLVMTM); 116 117 PassInstrumentationCallbacks PIC; 118 StandardInstrumentations SI(Context, Opt.DebugPM, !NoVerify); 119 registerCodeGenCallback(PIC, LLVMTM); 120 121 MachineFunctionAnalysisManager MFAM; 122 LoopAnalysisManager LAM; 123 FunctionAnalysisManager FAM; 124 CGSCCAnalysisManager CGAM; 125 ModuleAnalysisManager MAM; 126 PassBuilder PB(Target.get(), PipelineTuningOptions(), std::nullopt, &PIC); 127 PB.registerModuleAnalyses(MAM); 128 PB.registerCGSCCAnalyses(CGAM); 129 PB.registerFunctionAnalyses(FAM); 130 PB.registerLoopAnalyses(LAM); 131 PB.registerMachineFunctionAnalyses(MFAM); 132 PB.crossRegisterProxies(LAM, FAM, CGAM, MAM, &MFAM); 133 SI.registerCallbacks(PIC, &MAM); 134 135 FAM.registerPass([&] { return TargetLibraryAnalysis(TLII); }); 136 MAM.registerPass([&] { return MachineModuleAnalysis(MMI); }); 137 138 ModulePassManager MPM; 139 FunctionPassManager FPM; 140 141 if (!PassPipeline.empty()) { 142 // Construct a custom pass pipeline that starts after instruction 143 // selection. 144 145 if (!MIR) { 146 WithColor::warning(errs(), 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, PassPipeline)); 152 MPM.addPass(PrintMIRPreparePass(*OS)); 153 MachineFunctionPassManager MFPM; 154 MFPM.addPass(PrintMIRPass(*OS)); 155 FPM.addPass(createFunctionToMachineFunctionPassAdaptor(std::move(MFPM))); 156 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM))); 157 158 if (MIR->parseMachineFunctions(*M, MAM)) 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, [&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(*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