Path: blob/main/contrib/llvm-project/llvm/tools/llc/NewPMDriver.cpp
35231 views
//===- NewPMDriver.cpp - Driver for llc using new PM ----------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7/// \file8///9/// This file is just a split of the code that logically belongs in llc.cpp but10/// that includes the new pass manager headers.11///12//===----------------------------------------------------------------------===//1314#include "NewPMDriver.h"15#include "llvm/Analysis/CGSCCPassManager.h"16#include "llvm/Analysis/TargetLibraryInfo.h"17#include "llvm/CodeGen/CommandFlags.h"18#include "llvm/CodeGen/MIRParser/MIRParser.h"19#include "llvm/CodeGen/MIRPrinter.h"20#include "llvm/CodeGen/MachineModuleInfo.h"21#include "llvm/CodeGen/MachinePassManager.h"22#include "llvm/CodeGen/TargetPassConfig.h"23#include "llvm/IR/DiagnosticInfo.h"24#include "llvm/IR/DiagnosticPrinter.h"25#include "llvm/IR/IRPrintingPasses.h"26#include "llvm/IR/LLVMContext.h"27#include "llvm/IR/Module.h"28#include "llvm/IR/PassManager.h"29#include "llvm/IR/Verifier.h"30#include "llvm/IRReader/IRReader.h"31#include "llvm/Passes/CodeGenPassBuilder.h" // TODO: Include pass headers properly.32#include "llvm/Passes/PassBuilder.h"33#include "llvm/Passes/StandardInstrumentations.h"34#include "llvm/Support/CommandLine.h"35#include "llvm/Support/Debug.h"36#include "llvm/Support/Error.h"37#include "llvm/Support/ErrorHandling.h"38#include "llvm/Support/FormattedStream.h"39#include "llvm/Support/ToolOutputFile.h"40#include "llvm/Support/WithColor.h"41#include "llvm/Target/CGPassBuilderOption.h"42#include "llvm/Target/TargetMachine.h"43#include "llvm/Target/TargetOptions.h"44#include "llvm/Transforms/Scalar/LoopPassManager.h"45#include "llvm/Transforms/Utils/Cloning.h"4647namespace llvm {48extern cl::opt<bool> PrintPipelinePasses;49} // namespace llvm5051using namespace llvm;5253static cl::opt<std::string>54RegAlloc("regalloc-npm",55cl::desc("Register allocator to use for new pass manager"),56cl::Hidden, cl::init("default"));5758static cl::opt<bool>59DebugPM("debug-pass-manager", cl::Hidden,60cl::desc("Print pass management debugging information"));6162bool LLCDiagnosticHandler::handleDiagnostics(const DiagnosticInfo &DI) {63DiagnosticHandler::handleDiagnostics(DI);64if (DI.getKind() == llvm::DK_SrcMgr) {65const auto &DISM = cast<DiagnosticInfoSrcMgr>(DI);66const SMDiagnostic &SMD = DISM.getSMDiag();6768SMD.print(nullptr, errs());6970// For testing purposes, we print the LocCookie here.71if (DISM.isInlineAsmDiag() && DISM.getLocCookie())72WithColor::note() << "!srcloc = " << DISM.getLocCookie() << "\n";7374return true;75}7677if (auto *Remark = dyn_cast<DiagnosticInfoOptimizationBase>(&DI))78if (!Remark->isEnabled())79return true;8081DiagnosticPrinterRawOStream DP(errs());82errs() << LLVMContext::getDiagnosticMessagePrefix(DI.getSeverity()) << ": ";83DI.print(DP);84errs() << "\n";85return true;86}8788static llvm::ExitOnError ExitOnErr;8990int llvm::compileModuleWithNewPM(91StringRef Arg0, std::unique_ptr<Module> M, std::unique_ptr<MIRParser> MIR,92std::unique_ptr<TargetMachine> Target, std::unique_ptr<ToolOutputFile> Out,93std::unique_ptr<ToolOutputFile> DwoOut, LLVMContext &Context,94const TargetLibraryInfoImpl &TLII, bool NoVerify, StringRef PassPipeline,95CodeGenFileType FileType) {9697if (!PassPipeline.empty() && TargetPassConfig::hasLimitedCodeGenPipeline()) {98WithColor::warning(errs(), Arg0)99<< "--passes cannot be used with "100<< TargetPassConfig::getLimitedCodeGenPipelineReason() << ".\n";101return 1;102}103104LLVMTargetMachine &LLVMTM = static_cast<LLVMTargetMachine &>(*Target);105106raw_pwrite_stream *OS = &Out->os();107108// Fetch options from TargetPassConfig109CGPassBuilderOption Opt = getCGPassBuilderOption();110Opt.DisableVerify = NoVerify;111Opt.DebugPM = DebugPM;112Opt.RegAlloc = RegAlloc;113114MachineModuleInfo MMI(&LLVMTM);115116PassInstrumentationCallbacks PIC;117StandardInstrumentations SI(Context, Opt.DebugPM, !NoVerify);118registerCodeGenCallback(PIC, LLVMTM);119120MachineFunctionAnalysisManager MFAM;121LoopAnalysisManager LAM;122FunctionAnalysisManager FAM;123CGSCCAnalysisManager CGAM;124ModuleAnalysisManager MAM;125PassBuilder PB(Target.get(), PipelineTuningOptions(), std::nullopt, &PIC);126PB.registerModuleAnalyses(MAM);127PB.registerCGSCCAnalyses(CGAM);128PB.registerFunctionAnalyses(FAM);129PB.registerLoopAnalyses(LAM);130PB.registerMachineFunctionAnalyses(MFAM);131PB.crossRegisterProxies(LAM, FAM, CGAM, MAM, &MFAM);132SI.registerCallbacks(PIC, &MAM);133134FAM.registerPass([&] { return TargetLibraryAnalysis(TLII); });135MAM.registerPass([&] { return MachineModuleAnalysis(MMI); });136137ModulePassManager MPM;138FunctionPassManager FPM;139140if (!PassPipeline.empty()) {141// Construct a custom pass pipeline that starts after instruction142// selection.143144if (!MIR) {145WithColor::warning(errs(), Arg0) << "-passes is for .mir file only.\n";146return 1;147}148149// FIXME: verify that there are no IR passes.150ExitOnErr(PB.parsePassPipeline(MPM, PassPipeline));151MPM.addPass(PrintMIRPreparePass(*OS));152MachineFunctionPassManager MFPM;153MFPM.addPass(PrintMIRPass(*OS));154FPM.addPass(createFunctionToMachineFunctionPassAdaptor(std::move(MFPM)));155MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));156157if (MIR->parseMachineFunctions(*M, MAM))158return 1;159} else {160ExitOnErr(LLVMTM.buildCodeGenPipeline(161MPM, *OS, DwoOut ? &DwoOut->os() : nullptr, FileType, Opt, &PIC));162}163164if (PrintPipelinePasses) {165std::string PipelineStr;166raw_string_ostream OS(PipelineStr);167MPM.printPipeline(OS, [&PIC](StringRef ClassName) {168auto PassName = PIC.getPassNameForClassName(ClassName);169return PassName.empty() ? ClassName : PassName;170});171outs() << PipelineStr << '\n';172return 0;173}174175// Before executing passes, print the final values of the LLVM options.176cl::PrintOptionValues();177178MPM.run(*M, MAM);179180if (Context.getDiagHandlerPtr()->HasErrors)181exit(1);182183// Declare success.184Out->keep();185if (DwoOut)186DwoOut->keep();187188return 0;189}190191192