198 lines · cpp
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-exception6//7//===----------------------------------------------------------------------===//8/// \file9///10/// This file is just a split of the code that logically belongs in llc.cpp but11/// 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 49using namespace llvm;50 51static 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 56static cl::opt<bool>57 DebugPM("debug-pass-manager", cl::Hidden,58 cl::desc("Print pass management debugging information"));59 60bool 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 86static llvm::ExitOnError ExitOnErr;87 88int 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 std::unique_ptr<buffer_ostream> BOS;105 if (codegen::getFileType() != CodeGenFileType::AssemblyFile &&106 !Out->os().supportsSeeking()) {107 BOS = std::make_unique<buffer_ostream>(Out->os());108 OS = BOS.get();109 }110 111 // Fetch options from TargetPassConfig112 CGPassBuilderOption Opt = getCGPassBuilderOption();113 Opt.DisableVerify = VK != VerifierKind::InputOutput;114 Opt.DebugPM = DebugPM;115 Opt.RegAlloc = RegAlloc;116 117 MachineModuleInfo MMI(Target.get());118 119 PassInstrumentationCallbacks PIC;120 StandardInstrumentations SI(Context, Opt.DebugPM,121 VK == VerifierKind::EachPass);122 registerCodeGenCallback(PIC, *Target);123 124 MachineFunctionAnalysisManager MFAM;125 LoopAnalysisManager LAM;126 FunctionAnalysisManager FAM;127 CGSCCAnalysisManager CGAM;128 ModuleAnalysisManager MAM;129 PassBuilder PB(Target.get(), PipelineTuningOptions(), std::nullopt, &PIC);130 PB.registerModuleAnalyses(MAM);131 PB.registerCGSCCAnalyses(CGAM);132 PB.registerFunctionAnalyses(FAM);133 PB.registerLoopAnalyses(LAM);134 PB.registerMachineFunctionAnalyses(MFAM);135 PB.crossRegisterProxies(LAM, FAM, CGAM, MAM, &MFAM);136 SI.registerCallbacks(PIC, &MAM);137 138 FAM.registerPass([&] { return TargetLibraryAnalysis(TLII); });139 MAM.registerPass([&] { return MachineModuleAnalysis(MMI); });140 141 ModulePassManager MPM;142 FunctionPassManager FPM;143 144 if (!PassPipeline.empty()) {145 // Construct a custom pass pipeline that starts after instruction146 // selection.147 148 if (!MIR) {149 WithColor::error(errs(), Arg0) << "-passes is for .mir file only.\n";150 return 1;151 }152 153 // FIXME: verify that there are no IR passes.154 ExitOnErr(PB.parsePassPipeline(MPM, PassPipeline));155 MPM.addPass(PrintMIRPreparePass(*OS));156 MachineFunctionPassManager MFPM;157 if (VK == VerifierKind::InputOutput)158 MFPM.addPass(MachineVerifierPass());159 MFPM.addPass(PrintMIRPass(*OS));160 FPM.addPass(createFunctionToMachineFunctionPassAdaptor(std::move(MFPM)));161 MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));162 163 } else {164 ExitOnErr(Target->buildCodeGenPipeline(165 MPM, *OS, DwoOut ? &DwoOut->os() : nullptr, FileType, Opt, &PIC));166 }167 168 // If user only wants to print the pipeline, print it before parsing the MIR.169 if (PrintPipelinePasses) {170 std::string PipelineStr;171 raw_string_ostream OS(PipelineStr);172 MPM.printPipeline(OS, [&PIC](StringRef ClassName) {173 auto PassName = PIC.getPassNameForClassName(ClassName);174 return PassName.empty() ? ClassName : PassName;175 });176 outs() << PipelineStr << '\n';177 return 0;178 }179 180 if (MIR && MIR->parseMachineFunctions(*M, MAM))181 return 1;182 183 // Before executing passes, print the final values of the LLVM options.184 cl::PrintOptionValues();185 186 MPM.run(*M, MAM);187 188 if (Context.getDiagHandlerPtr()->HasErrors)189 exit(1);190 191 // Declare success.192 Out->keep();193 if (DwoOut)194 DwoOut->keep();195 196 return 0;197}198