| //===----------------------------------------------------------------------===// | |
| // | |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. | |
| // See https://llvm.org/LICENSE.txt for license information. | |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception | |
| // | |
| //===----------------------------------------------------------------------===// | |
| #include "llvm/Passes/RunCodeGen.h" | |
| #include "llvm/Analysis/CGSCCPassManager.h" | |
| #include "llvm/Analysis/LoopAnalysisManager.h" | |
| #include "llvm/Analysis/RuntimeLibcallInfo.h" | |
| #include "llvm/Analysis/TargetLibraryInfo.h" | |
| #include "llvm/Analysis/TargetTransformInfo.h" | |
| #include "llvm/CodeGen/MachineFunctionAnalysisManager.h" | |
| #include "llvm/CodeGen/MachineModuleInfo.h" | |
| #include "llvm/IR/LegacyPassManager.h" | |
| #include "llvm/IR/PassManager.h" | |
| #include "llvm/Passes/PassBuilder.h" | |
| #include "llvm/Support/CodeGen.h" | |
| #include "llvm/Support/Error.h" | |
| #include "llvm/Support/ToolOutputFile.h" | |
| #include "llvm/Support/raw_ostream.h" | |
| #include "llvm/Target/CGPassBuilderOption.h" | |
| using namespace llvm; | |
| static cl::opt<cl::boolOrDefault> | |
| ForceNewPM("force-new-pm-codegen", | |
| cl::desc("Whether to force the NewPM on/off. Not setting the " | |
| "option will default to what the target prefers."), | |
| cl::init(cl::boolOrDefault::BOU_UNSET)); | |
| static Error | |
| runCodeGenPipelineLegacy(TargetMachine &TM, Module &M, raw_pwrite_stream &OS, | |
| std::unique_ptr<ToolOutputFile> &DwoOS, | |
| CodeGenFileType CGFT, bool PrintPipelinePasses, | |
| bool DisableVerify, bool DisableSimplifyLibCalls) { | |
| legacy::PassManager CodeGenPasses; | |
| CodeGenPasses.add( | |
| createTargetTransformInfoWrapperPass(TM.getTargetIRAnalysis())); | |
| // Add LibraryInfo. | |
| TargetLibraryInfoImpl TLII(TM.getTargetTriple(), TM.Options.VecLib); | |
| if (DisableSimplifyLibCalls) | |
| TLII.disableAllFunctions(); | |
| CodeGenPasses.add(new TargetLibraryInfoWrapperPass(TLII)); | |
| const TargetOptions &Options = TM.Options; | |
| CodeGenPasses.add( | |
| new RuntimeLibraryInfoWrapper(Options.MCOptions.ABIName, Options.VecLib)); | |
| if (TM.addPassesToEmitFile(CodeGenPasses, OS, DwoOS ? &DwoOS->os() : nullptr, | |
| CGFT, DisableVerify)) | |
| return createStringError("Failed to construct CodeGen pipeline"); | |
| CodeGenPasses.run(M); | |
| return Error::success(); | |
| } | |
| static Error runCodeGenPipelineNewPM(TargetMachine &TM, Module &M, | |
| raw_pwrite_stream &OS, | |
| std::unique_ptr<ToolOutputFile> &DwoOS, | |
| CodeGenFileType CGFT, bool DisableVerify, | |
| IntrusiveRefCntPtr<vfs::FileSystem> VFS) { | |
| ModulePassManager MPM; | |
| MachineFunctionAnalysisManager MFAM; | |
| LoopAnalysisManager LAM; | |
| FunctionAnalysisManager FAM; | |
| CGSCCAnalysisManager CGAM; | |
| ModuleAnalysisManager MAM; | |
| CGPassBuilderOption Opt = getCGPassBuilderOption(); | |
| Opt.DisableVerify = DisableVerify; | |
| MachineModuleInfo MMI(&TM); | |
| PassInstrumentationCallbacks PIC; | |
| PipelineTuningOptions PTOptions; | |
| TargetMachine *TMPointer = &TM; | |
| PassBuilder PB(TMPointer, PTOptions, std::nullopt, &PIC, VFS); | |
| PB.registerModuleAnalyses(MAM); | |
| PB.registerCGSCCAnalyses(CGAM); | |
| PB.registerFunctionAnalyses(FAM); | |
| PB.registerLoopAnalyses(LAM); | |
| PB.registerMachineFunctionAnalyses(MFAM); | |
| PB.crossRegisterProxies(LAM, FAM, CGAM, MAM, &MFAM); | |
| MAM.registerPass([&] { return MachineModuleAnalysis(MMI); }); | |
| Error BuildPipelineError = | |
| TM.buildCodeGenPipeline(MPM, MAM, OS, DwoOS ? &DwoOS->os() : nullptr, | |
| CGFT, Opt, MMI.getContext(), &PIC); | |
| if (BuildPipelineError) | |
| return BuildPipelineError; | |
| MPM.run(M, MAM); | |
| return Error::success(); | |
| } | |
| Error llvm::runCodeGenPipeline(TargetMachine &TM, Module &M, | |
| raw_pwrite_stream &OS, | |
| std::unique_ptr<ToolOutputFile> &DwoOS, | |
| CodeGenFileType CGFT, bool PrintPipelinePasses, | |
| bool DisableVerify, bool DisableSimplifyLibCalls, | |
| IntrusiveRefCntPtr<vfs::FileSystem> VFS) { | |
| if (ForceNewPM == cl::boolOrDefault::BOU_TRUE || | |
| (TM.shouldDefaultToNewPM() && | |
| ForceNewPM != cl::boolOrDefault::BOU_FALSE)) { | |
| return runCodeGenPipelineNewPM(TM, M, OS, DwoOS, CGFT, DisableVerify, VFS); | |
| } | |
| return runCodeGenPipelineLegacy(TM, M, OS, DwoOS, CGFT, PrintPipelinePasses, | |
| DisableVerify, DisableSimplifyLibCalls); | |
| } |