<div dir="ltr">Thanks!</div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Fri, Sep 11, 2020 at 6:54 PM Chen, Yuanfang <<a href="mailto:Yuanfang.Chen@sony.com">Yuanfang.Chen@sony.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Thanks for the heads up. Reverted in ad99e34c59b80fd094a6acdbcde4869ff37dac87. I'll take a look.<br>
<br>
________________________________________<br>
From: David Blaikie <<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>><br>
Sent: Friday, September 11, 2020 6:41 PM<br>
To: Chen, Yuanfang; Yuanfang Chen; Matt Arsenault<br>
Cc: llvm-commits<br>
Subject: Re: [llvm] 31ecf8d - [NewPM][CodeGen] Introduce CodeGenPassBuilder to help build codegen pipeline<br>
<br>
+Matt Arsenault<mailto:<a href="mailto:arsenm2@gmail.com" target="_blank">arsenm2@gmail.com</a>> FYI (not that I expect anyone could/should've caught this in review - I wouldn't've, but just so everyone's aware of what's going on)<br>
<br>
I'll revert this in an hour or so if there's no other direction.<br>
<br>
On Fri, Sep 11, 2020 at 6:40 PM David Blaikie <<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a><mailto:<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>>> wrote:<br>
This commit introduces a circular dependency between llvm/lib/Target and llvm/lib/CodeGen (prior to this patch, CodeGen depended on Target, but not the other way around - with this patch, TargetMachine.h includes<br>
<br>
llvm/CodeGen/CGPassBuilderOption.h and llvm/CodeGen/MachinePassManager.h)<br>
<br>
Could you revert this patch to revisit the layering here before continuing? (that is, assuming fixing the layering would be more complicated than a few minutes/maybe an hour?)<br>
<br>
On Fri, Sep 11, 2020 at 4:41 PM Yuanfang Chen via llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><mailto:<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>>> wrote:<br>
<br>
Author: Yuanfang Chen<br>
Date: 2020-09-11T16:41:17-07:00<br>
New Revision: 31ecf8d29d81d196374a562c6d2bd2c25a62861e<br>
<br>
URL: <a href="https://github.com/llvm/llvm-project/commit/31ecf8d29d81d196374a562c6d2bd2c25a62861e" rel="noreferrer" target="_blank">https://github.com/llvm/llvm-project/commit/31ecf8d29d81d196374a562c6d2bd2c25a62861e</a><br>
DIFF: <a href="https://github.com/llvm/llvm-project/commit/31ecf8d29d81d196374a562c6d2bd2c25a62861e.diff" rel="noreferrer" target="_blank">https://github.com/llvm/llvm-project/commit/31ecf8d29d81d196374a562c6d2bd2c25a62861e.diff</a><br>
<br>
LOG: [NewPM][CodeGen] Introduce CodeGenPassBuilder to help build codegen pipeline<br>
<br>
Following up on D67687.<br>
Please refer to the RFC here <a href="http://lists.llvm.org/pipermail/llvm-dev/2020-July/143309.html" rel="noreferrer" target="_blank">http://lists.llvm.org/pipermail/llvm-dev/2020-July/143309.html</a><br>
<br>
`CodeGenPassBuilder` is the NPM counterpart of `TargetPassConfig` with below differences.<br>
- Debugging features (MIR print/verify, disable pass, start/stop-before/after, etc.) living in `TargetPassConfig` are moved to use PassInstrument as much as possible. (Implementation also lives in `TargetPassConfig.cpp`)<br>
- `TargetPassConfig` is a polymorphic base (virtual inheritance) to build the target-dependent pipeline whereas `CodeGenPassBuilder` is the CRTP base/helper to implement the target-dependent pipeline. The motivation is flexibility for targets to customize the pipeline, inlining opportunity, and fits the overall NPM value semantics design.<br>
- `TargetPassConfig` is a legacy immutable pass to declare hooks for targets to customize some target-independent codegen layer behavior. This is partially ported to TargetMachine::options. The rest, such as `createMachineScheduler/createPostMachineScheduler`, are left out for now. They should be implemented in LLVMTargetMachine in the future.<br>
<br>
Reviewed By: arsenm<br>
<br>
Differential Revision: <a href="https://reviews.llvm.org/D83608" rel="noreferrer" target="_blank">https://reviews.llvm.org/D83608</a><br>
<br>
Added:<br>
llvm/include/llvm/CodeGen/CGPassBuilderOption.h<br>
llvm/include/llvm/CodeGen/CodeGenPassBuilder.h<br>
llvm/include/llvm/CodeGen/MachinePassRegistry.def<br>
llvm/lib/CodeGen/CodeGenPassBuilder.cpp<br>
<br>
Modified:<br>
llvm/include/llvm/Passes/StandardInstrumentations.h<br>
llvm/include/llvm/Target/TargetMachine.h<br>
llvm/lib/CodeGen/CMakeLists.txt<br>
llvm/lib/CodeGen/LLVMTargetMachine.cpp<br>
llvm/lib/CodeGen/TargetPassConfig.cpp<br>
<br>
Removed:<br>
<br>
<br>
<br>
################################################################################<br>
diff --git a/llvm/include/llvm/CodeGen/CGPassBuilderOption.h b/llvm/include/llvm/CodeGen/CGPassBuilderOption.h<br>
new file mode 100644<br>
index 000000000000..4553060e687b<br>
--- /dev/null<br>
+++ b/llvm/include/llvm/CodeGen/CGPassBuilderOption.h<br>
@@ -0,0 +1,110 @@<br>
+//===- CGPassBuilderOption.h - Options for pass builder ---------*- C++ -*-===//<br>
+//<br>
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.<br>
+// See <a href="https://llvm.org/LICENSE.txt" rel="noreferrer" target="_blank">https://llvm.org/LICENSE.txt</a> for license information.<br>
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// This file declares the options influencing building of codegen pipeline.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#ifndef LLVM_CODEGEN_CGPASSBUILDEROPTION_H<br>
+#define LLVM_CODEGEN_CGPASSBUILDEROPTION_H<br>
+<br>
+#include "llvm/ADT/Optional.h"<br>
+#include "llvm/ADT/StringRef.h"<br>
+#include "llvm/Target/TargetOptions.h"<br>
+#include <vector><br>
+<br>
+namespace llvm {<br>
+class TargetMachine;<br>
+<br>
+enum class RunOutliner { TargetDefault, AlwaysOutline, NeverOutline };<br>
+enum class RegAllocType { Default, Basic, Fast, Greedy, PBQP };<br>
+enum class CFLAAType { None, Steensgaard, Andersen, Both };<br>
+<br>
+// Not one-on-one but mostly corresponding to commandline options in<br>
+// TargetPassConfig.cpp<br>
+struct CGPassBuilderOption {<br>
+ // Enable optimized register allocation compilation path<br>
+ Optional<bool> OptimizeRegAlloc;<br>
+<br>
+ // Enable interprocedural register allocation to reduce load/store at<br>
+ // procedure calls<br>
+ Optional<bool> EnableIPRA;<br>
+<br>
+ // Enable debug logging of pass pipeline<br>
+ bool DebugPM = false;<br>
+<br>
+ // Disable machine function verification<br>
+ bool DisableVerify = false;<br>
+<br>
+ // Fold null checks into faulting memory operations<br>
+ bool EnableImplicitNullChecksPass = false;<br>
+<br>
+ // Collect probability-driven block placement stats<br>
+ bool EnableMachineBlockPlacementStatsPass = false;<br>
+<br>
+ // Run MachineScheduler post regalloc (independent of preRA sched)<br>
+ bool EnablePostMachineSchedulerPass = false;<br>
+<br>
+ // Run live interval analysis earlier in the pipeline<br>
+ bool EnableLiveIntervalsPass = false;<br>
+<br>
+ // Disable Loop Strength Reduction Pass<br>
+ bool DisableLoopStrengthReducePass = false;<br>
+<br>
+ // Disable Codegen Prepare<br>
+ bool DisableCodeGenPreparePass = false;<br>
+<br>
+ // Disable MergeICmps Pass<br>
+ bool DisableMergeICmpsPass = false;<br>
+<br>
+ // Disable Partial Libcall Inlining Pass<br>
+ bool DisablePartiallyInlineLibCallsPass = false;<br>
+<br>
+ // Disable ConstantHoisting Pass<br>
+ bool DisableConstantHoistingPass = false;<br>
+<br>
+ // Print LLVM IR produced by the loop-reduce pass<br>
+ bool PrintAfterLSR = false;<br>
+<br>
+ // Print LLVM IR input to isel pass<br>
+ bool PrintISelInput = false;<br>
+<br>
+ // Dump garbage collector data<br>
+ bool PrintGCInfo = false;<br>
+<br>
+ // Enable codegen in SCC order.<br>
+ bool RequiresCodeGenSCCOrder = false;<br>
+<br>
+ // Enable the machine outliner<br>
+ RunOutliner EnableMachineOutliner = RunOutliner::TargetDefault;<br>
+<br>
+ // Register allocator to use<br>
+ RegAllocType RegAlloc = RegAllocType::Default;<br>
+<br>
+ // Experimental option to use CFL-AA in codegen<br>
+ CFLAAType UseCFLAA = CFLAAType::None;<br>
+<br>
+ // Enable abort calls when "global" instruction selection fails to<br>
+ // lower/select an instruction<br>
+ Optional<GlobalISelAbortMode> EnableGlobalISelAbort;<br>
+<br>
+ // Verify generated machine code"<br>
+ Optional<bool> VerifyMachineCode;<br>
+<br>
+ // Enable the "fast" instruction selector<br>
+ Optional<bool> EnableFastISelOption;<br>
+<br>
+ // Enable the "global" instruction selector<br>
+ Optional<bool> EnableGlobalISelOption;<br>
+};<br>
+<br>
+CGPassBuilderOption getCGPassBuilderOption();<br>
+<br>
+} // namespace llvm<br>
+<br>
+#endif // LLVM_CODEGEN_CGPASSBUILDEROPTION_H<br>
<br>
diff --git a/llvm/include/llvm/CodeGen/CodeGenPassBuilder.h b/llvm/include/llvm/CodeGen/CodeGenPassBuilder.h<br>
new file mode 100644<br>
index 000000000000..0c679eb174b7<br>
--- /dev/null<br>
+++ b/llvm/include/llvm/CodeGen/CodeGenPassBuilder.h<br>
@@ -0,0 +1,1171 @@<br>
+//===- Construction of codegen pass pipelines ------------------*- C++ -*--===//<br>
+//<br>
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.<br>
+// See <a href="https://llvm.org/LICENSE.txt" rel="noreferrer" target="_blank">https://llvm.org/LICENSE.txt</a> for license information.<br>
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+/// \file<br>
+///<br>
+/// Interfaces for registering analysis passes, producing common pass manager<br>
+/// configurations, and parsing of pass pipelines.<br>
+///<br>
+/// TODO: handle addRequiredID where, in legacy PM, one pass require other pass<br>
+/// to run as prerequisite.<br>
+///<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+#ifndef LLVM_CODEGEN_CODEGENPASSBUILDER_H<br>
+#define LLVM_CODEGEN_CODEGENPASSBUILDER_H<br>
+<br>
+#include "llvm/ADT/FunctionExtras.h"<br>
+#include "llvm/ADT/SmallVector.h"<br>
+#include "llvm/ADT/StringRef.h"<br>
+#include "llvm/Analysis/AliasAnalysis.h"<br>
+#include "llvm/Analysis/BasicAliasAnalysis.h"<br>
+#include "llvm/Analysis/CFLAndersAliasAnalysis.h"<br>
+#include "llvm/Analysis/CFLSteensAliasAnalysis.h"<br>
+#include "llvm/Analysis/ScopedNoAliasAA.h"<br>
+#include "llvm/Analysis/TargetTransformInfo.h"<br>
+#include "llvm/Analysis/TypeBasedAliasAnalysis.h"<br>
+#include "llvm/CodeGen/CGPassBuilderOption.h"<br>
+#include "llvm/CodeGen/ExpandReductions.h"<br>
+#include "llvm/CodeGen/MIRPrinter.h"<br>
+#include "llvm/CodeGen/MachineModuleInfo.h"<br>
+#include "llvm/CodeGen/MachinePassManager.h"<br>
+#include "llvm/CodeGen/PreISelIntrinsicLowering.h"<br>
+#include "llvm/CodeGen/UnreachableBlockElim.h"<br>
+#include "llvm/IR/IRPrintingPasses.h"<br>
+#include "llvm/IR/PassManager.h"<br>
+#include "llvm/IR/Verifier.h"<br>
+#include "llvm/MC/MCAsmInfo.h"<br>
+#include "llvm/MC/MCStreamer.h"<br>
+#include "llvm/MC/MCTargetOptions.h"<br>
+#include "llvm/Support/CodeGen.h"<br>
+#include "llvm/Support/Debug.h"<br>
+#include "llvm/Support/Error.h"<br>
+#include "llvm/Support/ErrorHandling.h"<br>
+#include "llvm/Target/TargetMachine.h"<br>
+#include "llvm/Transforms/Scalar.h"<br>
+#include "llvm/Transforms/Scalar/ConstantHoisting.h"<br>
+#include "llvm/Transforms/Scalar/LoopPassManager.h"<br>
+#include "llvm/Transforms/Scalar/LoopStrengthReduce.h"<br>
+#include "llvm/Transforms/Scalar/LowerConstantIntrinsics.h"<br>
+#include "llvm/Transforms/Scalar/MergeICmps.h"<br>
+#include "llvm/Transforms/Scalar/PartiallyInlineLibCalls.h"<br>
+#include "llvm/Transforms/Utils.h"<br>
+#include "llvm/Transforms/Utils/EntryExitInstrumenter.h"<br>
+#include "llvm/Transforms/Utils/LowerInvoke.h"<br>
+#include <cassert><br>
+#include <string><br>
+#include <type_traits><br>
+#include <utility><br>
+#include <vector><br>
+<br>
+namespace llvm {<br>
+<br>
+// FIXME: Dummy target independent passes definitions that have not yet been<br>
+// ported to new pass manager. Once they do, remove these.<br>
+#define DUMMY_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR) \<br>
+ struct PASS_NAME : public PassInfoMixin<PASS_NAME> { \<br>
+ template <typename... Ts> PASS_NAME(Ts &&...) {} \<br>
+ PreservedAnalyses run(Function &, FunctionAnalysisManager &) { \<br>
+ return PreservedAnalyses::all(); \<br>
+ } \<br>
+ };<br>
+#define DUMMY_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR) \<br>
+ struct PASS_NAME : public PassInfoMixin<PASS_NAME> { \<br>
+ template <typename... Ts> PASS_NAME(Ts &&...) {} \<br>
+ PreservedAnalyses run(Module &, ModuleAnalysisManager &) { \<br>
+ return PreservedAnalyses::all(); \<br>
+ } \<br>
+ };<br>
+#define DUMMY_MACHINE_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR) \<br>
+ struct PASS_NAME : public PassInfoMixin<PASS_NAME> { \<br>
+ template <typename... Ts> PASS_NAME(Ts &&...) {} \<br>
+ Error run(Module &, MachineFunctionAnalysisManager &) { \<br>
+ return Error::success(); \<br>
+ } \<br>
+ PreservedAnalyses run(MachineFunction &, \<br>
+ MachineFunctionAnalysisManager &) { \<br>
+ llvm_unreachable("this api is to make new PM api happy"); \<br>
+ } \<br>
+ static AnalysisKey Key; \<br>
+ };<br>
+#define DUMMY_MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR) \<br>
+ struct PASS_NAME : public PassInfoMixin<PASS_NAME> { \<br>
+ template <typename... Ts> PASS_NAME(Ts &&...) {} \<br>
+ PreservedAnalyses run(MachineFunction &, \<br>
+ MachineFunctionAnalysisManager &) { \<br>
+ return PreservedAnalyses::all(); \<br>
+ } \<br>
+ static AnalysisKey Key; \<br>
+ };<br>
+#include "MachinePassRegistry.def"<br>
+<br>
+/// This class provides access to building LLVM's passes.<br>
+///<br>
+/// Its members provide the baseline state available to passes during their<br>
+/// construction. The \c MachinePassRegistry.def file specifies how to construct<br>
+/// all of the built-in passes, and those may reference these members during<br>
+/// construction.<br>
+template <typename DerivedT> class CodeGenPassBuilder {<br>
+public:<br>
+ explicit CodeGenPassBuilder(LLVMTargetMachine &TM, CGPassBuilderOption Opts,<br>
+ PassInstrumentationCallbacks *PIC)<br>
+ : TM(TM), Opt(Opts), PIC(PIC) {<br>
+ // Target could set CGPassBuilderOption::MISchedPostRA to true to achieve<br>
+ // substitutePass(&PostRASchedulerID, &PostMachineSchedulerID)<br>
+<br>
+ // Target should override TM.Options.EnableIPRA in their target-specific<br>
+ // LLVMTM ctor. See TargetMachine::setGlobalISel for example.<br>
+ if (Opt.EnableIPRA)<br>
+ TM.Options.EnableIPRA = *Opt.EnableIPRA;<br>
+<br>
+ if (Opt.EnableGlobalISelAbort)<br>
+ TM.Options.GlobalISelAbort = *Opt.EnableGlobalISelAbort;<br>
+<br>
+ if (!Opt.OptimizeRegAlloc)<br>
+ Opt.OptimizeRegAlloc = getOptLevel() != CodeGenOpt::None;<br>
+<br>
+ if (!Opt.VerifyMachineCode) {<br>
+#ifdef EXPENSIVE_CHECKS<br>
+ Opt.VerifyMachineCode = TM->isMachineVerifierClean();<br>
+#else<br>
+ Opt.VerifyMachineCode = false;<br>
+#endif<br>
+ }<br>
+ }<br>
+<br>
+ Expected<std::pair<ModulePassManager, MachineFunctionPassManager>><br>
+ buildPipeline(raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,<br>
+ CodeGenFileType FileType) const;<br>
+<br>
+ void registerModuleAnalyses(ModuleAnalysisManager &) const;<br>
+ void registerFunctionAnalyses(FunctionAnalysisManager &) const;<br>
+ void registerMachineFunctionAnalyses(MachineFunctionAnalysisManager &) const;<br>
+ std::pair<StringRef, bool> getPassNameFromLegacyName(StringRef) const;<br>
+<br>
+ void registerAnalyses(MachineFunctionAnalysisManager &MFAM) const {<br>
+ registerModuleAnalyses(*MFAM.MAM);<br>
+ registerFunctionAnalyses(*MFAM.FAM);<br>
+ registerMachineFunctionAnalyses(MFAM);<br>
+ }<br>
+<br>
+ PassInstrumentationCallbacks *getPassInstrumentationCallbacks() const {<br>
+ return PIC;<br>
+ }<br>
+<br>
+protected:<br>
+ template <typename PassT> using has_key_t = decltype(PassT::Key);<br>
+<br>
+ template <typename PassT><br>
+ using is_module_pass_t = decltype(std::declval<PassT &>().run(<br>
+ std::declval<Module &>(), std::declval<ModuleAnalysisManager &>()));<br>
+<br>
+ template <typename PassT><br>
+ using is_function_pass_t = decltype(std::declval<PassT &>().run(<br>
+ std::declval<Function &>(), std::declval<FunctionAnalysisManager &>()));<br>
+<br>
+ // Function object to maintain state while adding codegen IR passes.<br>
+ class AddIRPass {<br>
+ public:<br>
+ AddIRPass(bool DebugPM) : MPM(DebugPM), FPM(DebugPM) {<br>
+ AddingFunctionPasses = false;<br>
+ }<br>
+<br>
+ // Add Function Pass<br>
+ template <typename PassT><br>
+ std::enable_if_t<is_detected<is_function_pass_t, PassT>::value><br>
+ operator()(PassT &&Pass) {<br>
+ if (!AddingFunctionPasses)<br>
+ AddingFunctionPasses = true;<br>
+ FPM.addPass(std::forward<PassT>(Pass));<br>
+ }<br>
+<br>
+ // Add Module Pass<br>
+ template <typename PassT><br>
+ std::enable_if_t<is_detected<is_module_pass_t, PassT>::value &&<br>
+ !is_detected<is_function_pass_t, PassT>::value><br>
+ operator()(PassT &&Pass) {<br>
+ assert((!AddingFunctionPasses) &&<br>
+ "could not add module pass after adding function pass");<br>
+ MPM.addPass(std::forward<PassT>(Pass));<br>
+ }<br>
+<br>
+ ModulePassManager releasePM() {<br>
+ MPM.addPass(createModuleToFunctionPassAdaptor(std::move(FPM)));<br>
+ return std::move(MPM);<br>
+ }<br>
+<br>
+ private:<br>
+ ModulePassManager MPM;<br>
+ FunctionPassManager FPM;<br>
+ // The codegen IR pipeline are mostly function passes with the exceptions of<br>
+ // a few loop and module passes. `AddingFunctionPasses` makes sure that<br>
+ // we could only add module passes at the beginning of the pipeline. Once<br>
+ // we begin adding function passes, we could no longer add module passes.<br>
+ // This special-casing introduces less adaptor passes. If we have the need<br>
+ // of adding module passes after function passes, we could change the<br>
+ // implementation to accommodate that.<br>
+ bool AddingFunctionPasses;<br>
+ };<br>
+<br>
+ // Function object to maintain state while adding codegen machine passes.<br>
+ class AddMachinePass {<br>
+ public:<br>
+ AddMachinePass(bool DebugPM, bool RequiresCodeGenSCCOrder,<br>
+ bool VerifyMachineCode)<br>
+ : PM(DebugPM, RequiresCodeGenSCCOrder, VerifyMachineCode) {}<br>
+<br>
+ template <typename PassT> void operator()(PassT &&Pass) {<br>
+ static_assert(<br>
+ is_detected<has_key_t, PassT>::value,<br>
+ "Machine function pass must define a static member variable `Key`.");<br>
+ for (auto &C : BeforeCallbacks) {<br>
+ if (!C(&PassT::Key))<br>
+ return;<br>
+ }<br>
+ PM.addPass(std::forward<PassT>(Pass));<br>
+ for (auto &C : AfterCallbacks)<br>
+ C(&PassT::Key);<br>
+ }<br>
+<br>
+ template <typename PassT> void insertPass(AnalysisKey *ID, PassT Pass) {<br>
+ AfterCallbacks.emplace_back(<br>
+ [this, ID, Pass = std::move(Pass)](AnalysisKey *PassID) {<br>
+ if (PassID == ID)<br>
+ this->PM.addPass(std::move(Pass));<br>
+ });<br>
+ }<br>
+<br>
+ void disablePass(AnalysisKey *ID) {<br>
+ BeforeCallbacks.emplace_back(<br>
+ [ID](AnalysisKey *PassID) { return PassID != ID; });<br>
+ }<br>
+<br>
+ MachineFunctionPassManager releasePM() { return std::move(PM); }<br>
+<br>
+ private:<br>
+ MachineFunctionPassManager PM;<br>
+ SmallVector<llvm::unique_function<bool(AnalysisKey *)>, 4> BeforeCallbacks;<br>
+ SmallVector<llvm::unique_function<void(AnalysisKey *)>, 4> AfterCallbacks;<br>
+ };<br>
+<br>
+ LLVMTargetMachine &TM;<br>
+ CGPassBuilderOption Opt;<br>
+ PassInstrumentationCallbacks *PIC;<br>
+<br>
+ /// Target override these hooks to parse target-specific analyses.<br>
+ void registerTargetAnalysis(ModuleAnalysisManager &) const {}<br>
+ void registerTargetAnalysis(FunctionAnalysisManager &) const {}<br>
+ void registerTargetAnalysis(MachineFunctionAnalysisManager &) const {}<br>
+ std::pair<StringRef, bool> getTargetPassNameFromLegacyName(StringRef) const {<br>
+ return {"", false};<br>
+ }<br>
+<br>
+ template <typename TMC> TMC &getTM() const { return static_cast<TMC &>(TM); }<br>
+ CodeGenOpt::Level getOptLevel() const { return TM.getOptLevel(); }<br>
+<br>
+ /// Check whether or not GlobalISel should abort on error.<br>
+ /// When this is disabled, GlobalISel will fall back on SDISel instead of<br>
+ /// erroring out.<br>
+ bool isGlobalISelAbortEnabled() const {<br>
+ return TM.Options.GlobalISelAbort == GlobalISelAbortMode::Enable;<br>
+ }<br>
+<br>
+ /// Check whether or not a diagnostic should be emitted when GlobalISel<br>
+ /// uses the fallback path. In other words, it will emit a diagnostic<br>
+ /// when GlobalISel failed and isGlobalISelAbortEnabled is false.<br>
+ bool reportDiagnosticWhenGlobalISelFallback() const {<br>
+ return TM.Options.GlobalISelAbort == GlobalISelAbortMode::DisableWithDiag;<br>
+ }<br>
+<br>
+ /// addInstSelector - This method should install an instruction selector pass,<br>
+ /// which converts from LLVM code to machine instructions.<br>
+ Error addInstSelector(AddMachinePass &) const {<br>
+ return make_error<StringError>("addInstSelector is not overridden",<br>
+ inconvertibleErrorCode());<br>
+ }<br>
+<br>
+ /// Add passes that optimize instruction level parallelism for out-of-order<br>
+ /// targets. These passes are run while the machine code is still in SSA<br>
+ /// form, so they can use MachineTraceMetrics to control their heuristics.<br>
+ ///<br>
+ /// All passes added here should preserve the MachineDominatorTree,<br>
+ /// MachineLoopInfo, and MachineTraceMetrics analyses.<br>
+ void addILPOpts(AddMachinePass &) const {}<br>
+<br>
+ /// This method may be implemented by targets that want to run passes<br>
+ /// immediately before register allocation.<br>
+ void addPreRegAlloc(AddMachinePass &) const {}<br>
+<br>
+ /// addPreRewrite - Add passes to the optimized register allocation pipeline<br>
+ /// after register allocation is complete, but before virtual registers are<br>
+ /// rewritten to physical registers.<br>
+ ///<br>
+ /// These passes must preserve VirtRegMap and LiveIntervals, and when running<br>
+ /// after RABasic or RAGreedy, they should take advantage of LiveRegMatrix.<br>
+ /// When these passes run, VirtRegMap contains legal physreg assignments for<br>
+ /// all virtual registers.<br>
+ ///<br>
+ /// Note if the target overloads addRegAssignAndRewriteOptimized, this may not<br>
+ /// be honored. This is also not generally used for the the fast variant,<br>
+ /// where the allocation and rewriting are done in one pass.<br>
+ void addPreRewrite(AddMachinePass &) const {}<br>
+<br>
+ /// Add passes to be run immediately after virtual registers are rewritten<br>
+ /// to physical registers.<br>
+ void addPostRewrite(AddMachinePass &) const {}<br>
+<br>
+ /// This method may be implemented by targets that want to run passes after<br>
+ /// register allocation pass pipeline but before prolog-epilog insertion.<br>
+ void addPostRegAlloc(AddMachinePass &) const {}<br>
+<br>
+ /// This method may be implemented by targets that want to run passes after<br>
+ /// prolog-epilog insertion and before the second instruction scheduling pass.<br>
+ void addPreSched2(AddMachinePass &) const {}<br>
+<br>
+ /// This pass may be implemented by targets that want to run passes<br>
+ /// immediately before machine code is emitted.<br>
+ void addPreEmitPass(AddMachinePass &) const {}<br>
+<br>
+ /// Targets may add passes immediately before machine code is emitted in this<br>
+ /// callback. This is called even later than `addPreEmitPass`.<br>
+ // FIXME: Rename `addPreEmitPass` to something more sensible given its actual<br>
+ // position and remove the `2` suffix here as this callback is what<br>
+ // `addPreEmitPass` *should* be but in reality isn't.<br>
+ void addPreEmitPass2(AddMachinePass &) const {}<br>
+<br>
+ /// {{@ For GlobalISel<br>
+ ///<br>
+<br>
+ /// addPreISel - This method should add any "last minute" LLVM->LLVM<br>
+ /// passes (which are run just before instruction selector).<br>
+ void addPreISel(AddIRPass &) const {<br>
+ llvm_unreachable("addPreISel is not overridden");<br>
+ }<br>
+<br>
+ /// This method should install an IR translator pass, which converts from<br>
+ /// LLVM code to machine instructions with possibly generic opcodes.<br>
+ Error addIRTranslator(AddMachinePass &) const {<br>
+ return make_error<StringError>("addIRTranslator is not overridden",<br>
+ inconvertibleErrorCode());<br>
+ }<br>
+<br>
+ /// This method may be implemented by targets that want to run passes<br>
+ /// immediately before legalization.<br>
+ void addPreLegalizeMachineIR(AddMachinePass &) const {}<br>
+<br>
+ /// This method should install a legalize pass, which converts the instruction<br>
+ /// sequence into one that can be selected by the target.<br>
+ Error addLegalizeMachineIR(AddMachinePass &) const {<br>
+ return make_error<StringError>("addLegalizeMachineIR is not overridden",<br>
+ inconvertibleErrorCode());<br>
+ }<br>
+<br>
+ /// This method may be implemented by targets that want to run passes<br>
+ /// immediately before the register bank selection.<br>
+ void addPreRegBankSelect(AddMachinePass &) const {}<br>
+<br>
+ /// This method should install a register bank selector pass, which<br>
+ /// assigns register banks to virtual registers without a register<br>
+ /// class or register banks.<br>
+ Error addRegBankSelect(AddMachinePass &) const {<br>
+ return make_error<StringError>("addRegBankSelect is not overridden",<br>
+ inconvertibleErrorCode());<br>
+ }<br>
+<br>
+ /// This method may be implemented by targets that want to run passes<br>
+ /// immediately before the (global) instruction selection.<br>
+ void addPreGlobalInstructionSelect(AddMachinePass &) const {}<br>
+<br>
+ /// This method should install a (global) instruction selector pass, which<br>
+ /// converts possibly generic instructions to fully target-specific<br>
+ /// instructions, thereby constraining all generic virtual registers to<br>
+ /// register classes.<br>
+ Error addGlobalInstructionSelect(AddMachinePass &) const {<br>
+ return make_error<StringError>(<br>
+ "addGlobalInstructionSelect is not overridden",<br>
+ inconvertibleErrorCode());<br>
+ }<br>
+ /// @}}<br>
+<br>
+ /// High level function that adds all passes necessary to go from llvm IR<br>
+ /// representation to the MI representation.<br>
+ /// Adds IR based lowering and target specific optimization passes and finally<br>
+ /// the core instruction selection passes.<br>
+ /// \returns true if an error occurred, false otherwise.<br>
+ ModulePassManager addISelPasses() const;<br>
+<br>
+ /// Add the actual instruction selection passes. This does not include<br>
+ /// preparation passes on IR.<br>
+ Expected<AddMachinePass> addCoreISelPasses() const;<br>
+<br>
+ /// Add the complete, standard set of LLVM CodeGen passes.<br>
+ /// Fully developed targets will not generally override this.<br>
+ Error addMachinePasses(AddMachinePass &) const;<br>
+<br>
+ /// Add passes to lower exception handling for the code generator.<br>
+ void addPassesToHandleExceptions(AddIRPass &) const;<br>
+<br>
+ /// Add common target configurable passes that perform LLVM IR to IR<br>
+ /// transforms following machine independent optimization.<br>
+ void addIRPasses(AddIRPass &) const;<br>
+<br>
+ /// Add pass to prepare the LLVM IR for code generation. This should be done<br>
+ /// before exception handling preparation passes.<br>
+ void addCodeGenPrepare(AddIRPass &) const;<br>
+<br>
+ /// Add common passes that perform LLVM IR to IR transforms in preparation for<br>
+ /// instruction selection.<br>
+ void addISelPrepare(AddIRPass &) const;<br>
+<br>
+ /// Methods with trivial inline returns are convenient points in the common<br>
+ /// codegen pass pipeline where targets may insert passes. Methods with<br>
+ /// out-of-line standard implementations are major CodeGen stages called by<br>
+ /// addMachinePasses. Some targets may override major stages when inserting<br>
+ /// passes is insufficient, but maintaining overriden stages is more work.<br>
+ ///<br>
+<br>
+ /// addMachineSSAOptimization - Add standard passes that optimize machine<br>
+ /// instructions in SSA form.<br>
+ void addMachineSSAOptimization(AddMachinePass &) const;<br>
+<br>
+ /// addFastRegAlloc - Add the minimum set of target-independent passes that<br>
+ /// are required for fast register allocation.<br>
+ Error addFastRegAlloc(AddMachinePass &) const;<br>
+<br>
+ /// addOptimizedRegAlloc - Add passes related to register allocation.<br>
+ /// LLVMTargetMachine provides standard regalloc passes for most targets.<br>
+ void addOptimizedRegAlloc(AddMachinePass &) const;<br>
+<br>
+ /// Add passes that optimize machine instructions after register allocation.<br>
+ void addMachineLateOptimization(AddMachinePass &) const;<br>
+<br>
+ /// addGCPasses - Add late codegen passes that analyze code for garbage<br>
+ /// collection. This should return true if GC info should be printed after<br>
+ /// these passes.<br>
+ void addGCPasses(AddMachinePass &) const {}<br>
+<br>
+ /// Add standard basic block placement passes.<br>
+ void addBlockPlacement(AddMachinePass &) const;<br>
+<br>
+ using CreateMCStreamer =<br>
+ std::function<Expected<std::unique_ptr<MCStreamer>>(MCContext &)>;<br>
+ void addAsmPrinter(AddMachinePass &, CreateMCStreamer) const {<br>
+ llvm_unreachable("addAsmPrinter is not overridden");<br>
+ }<br>
+<br>
+ /// Utilities for targets to add passes to the pass manager.<br>
+ ///<br>
+<br>
+ /// createTargetRegisterAllocator - Create the register allocator pass for<br>
+ /// this target at the current optimization level.<br>
+ void addTargetRegisterAllocator(AddMachinePass &, bool Optimized) const;<br>
+<br>
+ /// addMachinePasses helper to create the target-selected or overriden<br>
+ /// regalloc pass.<br>
+ void addRegAllocPass(AddMachinePass &, bool Optimized) const;<br>
+<br>
+ /// Add core register alloator passes which do the actual register assignment<br>
+ /// and rewriting. \returns true if any passes were added.<br>
+ Error addRegAssignmentFast(AddMachinePass &) const;<br>
+ Error addRegAssignmentOptimized(AddMachinePass &) const;<br>
+<br>
+private:<br>
+ DerivedT &derived() { return static_cast<DerivedT &>(*this); }<br>
+ const DerivedT &derived() const {<br>
+ return static_cast<const DerivedT &>(*this);<br>
+ }<br>
+};<br>
+<br>
+template <typename Derived><br>
+Expected<std::pair<ModulePassManager, MachineFunctionPassManager>><br>
+CodeGenPassBuilder<Derived>::buildPipeline(raw_pwrite_stream &Out,<br>
+ raw_pwrite_stream *DwoOut,<br>
+ CodeGenFileType FileType) const {<br>
+ Expected<AddMachinePass> AddPassOrErr = addCoreISelPasses();<br>
+ if (!AddPassOrErr)<br>
+ return AddPassOrErr.takeError();<br>
+<br>
+ AddMachinePass &addPass = *AddPassOrErr;<br>
+<br>
+ if (auto Err = derived().addMachinePasses(addPass))<br>
+ return std::move(Err);<br>
+<br>
+ derived().addAsmPrinter(<br>
+ addPass, [this, &Out, DwoOut, FileType](MCContext &Ctx) {<br>
+ return this->TM.createMCStreamer(Out, DwoOut, FileType, Ctx);<br>
+ });<br>
+<br>
+ addPass(FreeMachineFunctionPass());<br>
+<br>
+ return std::pair<ModulePassManager, MachineFunctionPassManager>{<br>
+ addISelPasses(), addPass.releasePM()};<br>
+}<br>
+<br>
+static inline AAManager registerAAAnalyses(CFLAAType UseCFLAA) {<br>
+ AAManager AA;<br>
+<br>
+ // The order in which these are registered determines their priority when<br>
+ // being queried.<br>
+<br>
+ switch (UseCFLAA) {<br>
+ case CFLAAType::Steensgaard:<br>
+ AA.registerFunctionAnalysis<CFLSteensAA>();<br>
+ break;<br>
+ case CFLAAType::Andersen:<br>
+ AA.registerFunctionAnalysis<CFLAndersAA>();<br>
+ break;<br>
+ case CFLAAType::Both:<br>
+ AA.registerFunctionAnalysis<CFLAndersAA>();<br>
+ AA.registerFunctionAnalysis<CFLSteensAA>();<br>
+ break;<br>
+ default:<br>
+ break;<br>
+ }<br>
+<br>
+ // Basic AliasAnalysis support.<br>
+ // Add TypeBasedAliasAnalysis before BasicAliasAnalysis so that<br>
+ // BasicAliasAnalysis wins if they disagree. This is intended to help<br>
+ // support "obvious" type-punning idioms.<br>
+ AA.registerFunctionAnalysis<TypeBasedAA>();<br>
+ AA.registerFunctionAnalysis<ScopedNoAliasAA>();<br>
+ AA.registerFunctionAnalysis<BasicAA>();<br>
+<br>
+ return AA;<br>
+}<br>
+<br>
+template <typename Derived><br>
+void CodeGenPassBuilder<Derived>::registerModuleAnalyses(<br>
+ ModuleAnalysisManager &MAM) const {<br>
+#define MODULE_ANALYSIS(NAME, PASS_NAME, CONSTRUCTOR) \<br>
+ MAM.registerPass([&] { return PASS_NAME CONSTRUCTOR; });<br>
+#include "MachinePassRegistry.def"<br>
+ derived().registerTargetAnalysis(MAM);<br>
+}<br>
+<br>
+template <typename Derived><br>
+void CodeGenPassBuilder<Derived>::registerFunctionAnalyses(<br>
+ FunctionAnalysisManager &FAM) const {<br>
+ FAM.registerPass([this] { return registerAAAnalyses(this->Opt.UseCFLAA); });<br>
+<br>
+#define FUNCTION_ANALYSIS(NAME, PASS_NAME, CONSTRUCTOR) \<br>
+ FAM.registerPass([&] { return PASS_NAME CONSTRUCTOR; });<br>
+#include "MachinePassRegistry.def"<br>
+ derived().registerTargetAnalysis(FAM);<br>
+}<br>
+<br>
+template <typename Derived><br>
+void CodeGenPassBuilder<Derived>::registerMachineFunctionAnalyses(<br>
+ MachineFunctionAnalysisManager &MFAM) const {<br>
+#define MACHINE_FUNCTION_ANALYSIS(NAME, PASS_NAME, CONSTRUCTOR) \<br>
+ MFAM.registerPass([&] { return PASS_NAME CONSTRUCTOR; });<br>
+#include "MachinePassRegistry.def"<br>
+ derived().registerTargetAnalysis(MFAM);<br>
+}<br>
+<br>
+// FIXME: For new PM, use pass name directly in commandline seems good.<br>
+// Translate stringfied pass name to its old commandline name. Returns the<br>
+// matching legacy name and a boolean value indicating if the pass is a machine<br>
+// pass.<br>
+template <typename Derived><br>
+std::pair<StringRef, bool><br>
+CodeGenPassBuilder<Derived>::getPassNameFromLegacyName(StringRef Name) const {<br>
+ std::pair<StringRef, bool> Ret;<br>
+ if (Name.empty())<br>
+ return Ret;<br>
+<br>
+#define FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR) \<br>
+ if (Name == NAME) \<br>
+ Ret = {#PASS_NAME, false};<br>
+#define DUMMY_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR) \<br>
+ if (Name == NAME) \<br>
+ Ret = {#PASS_NAME, false};<br>
+#define MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR) \<br>
+ if (Name == NAME) \<br>
+ Ret = {#PASS_NAME, false};<br>
+#define DUMMY_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR) \<br>
+ if (Name == NAME) \<br>
+ Ret = {#PASS_NAME, false};<br>
+#define MACHINE_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR) \<br>
+ if (Name == NAME) \<br>
+ Ret = {#PASS_NAME, true};<br>
+#define DUMMY_MACHINE_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR) \<br>
+ if (Name == NAME) \<br>
+ Ret = {#PASS_NAME, true};<br>
+#define MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR) \<br>
+ if (Name == NAME) \<br>
+ Ret = {#PASS_NAME, true};<br>
+#define DUMMY_MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR) \<br>
+ if (Name == NAME) \<br>
+ Ret = {#PASS_NAME, true};<br>
+#include "llvm/CodeGen/MachinePassRegistry.def"<br>
+<br>
+ if (Ret.first.empty())<br>
+ Ret = derived().getTargetPassNameFromLegacyName(Name);<br>
+<br>
+ if (Ret.first.empty())<br>
+ report_fatal_error(Twine('\"') + Twine(Name) +<br>
+ Twine("\" pass could not be found."));<br>
+<br>
+ return Ret;<br>
+}<br>
+<br>
+template <typename Derived><br>
+ModulePassManager CodeGenPassBuilder<Derived>::addISelPasses() const {<br>
+ AddIRPass addPass(Opt.DebugPM);<br>
+<br>
+ if (TM.useEmulatedTLS())<br>
+ addPass(LowerEmuTLSPass());<br>
+<br>
+ addPass(PreISelIntrinsicLoweringPass());<br>
+<br>
+ derived().addIRPasses(addPass);<br>
+ derived().addCodeGenPrepare(addPass);<br>
+ addPassesToHandleExceptions(addPass);<br>
+ derived().addISelPrepare(addPass);<br>
+ return addPass.releasePM();<br>
+}<br>
+<br>
+/// Add common target configurable passes that perform LLVM IR to IR transforms<br>
+/// following machine independent optimization.<br>
+template <typename Derived><br>
+void CodeGenPassBuilder<Derived>::addIRPasses(AddIRPass &addPass) const {<br>
+ // Before running any passes, run the verifier to determine if the input<br>
+ // coming from the front-end and/or optimizer is valid.<br>
+ if (!Opt.DisableVerify)<br>
+ addPass(VerifierPass());<br>
+<br>
+ // Run loop strength reduction before anything else.<br>
+ if (getOptLevel() != CodeGenOpt::None && !Opt.DisableLoopStrengthReducePass) {<br>
+ addPass(createFunctionToLoopPassAdaptor(<br>
+ LoopStrengthReducePass(), /*UseMemorySSA*/ true, Opt.DebugPM));<br>
+ // FIXME: use -stop-after so we could remove PrintAfterLSR<br>
+ if (Opt.PrintAfterLSR)<br>
+ addPass(PrintFunctionPass(dbgs(), "\n\n*** Code after LSR ***\n"));<br>
+ }<br>
+<br>
+ if (getOptLevel() != CodeGenOpt::None) {<br>
+ // The MergeICmpsPass tries to create memcmp calls by grouping sequences of<br>
+ // loads and compares. ExpandMemCmpPass then tries to expand those calls<br>
+ // into optimally-sized loads and compares. The transforms are enabled by a<br>
+ // target lowering hook.<br>
+ if (!Opt.DisableMergeICmpsPass)<br>
+ addPass(MergeICmpsPass());<br>
+ addPass(ExpandMemCmpPass());<br>
+ }<br>
+<br>
+ // Run GC lowering passes for builtin collectors<br>
+ // TODO: add a pass insertion point here<br>
+ addPass(GCLoweringPass());<br>
+ addPass(ShadowStackGCLoweringPass());<br>
+ addPass(LowerConstantIntrinsicsPass());<br>
+<br>
+ // Make sure that no unreachable blocks are instruction selected.<br>
+ addPass(UnreachableBlockElimPass());<br>
+<br>
+ // Prepare expensive constants for SelectionDAG.<br>
+ if (getOptLevel() != CodeGenOpt::None && !Opt.DisableConstantHoistingPass)<br>
+ addPass(ConstantHoistingPass());<br>
+<br>
+ if (getOptLevel() != CodeGenOpt::None &&<br>
+ !Opt.DisablePartiallyInlineLibCallsPass)<br>
+ addPass(PartiallyInlineLibCallsPass());<br>
+<br>
+ // Instrument function entry and exit, e.g. with calls to mcount().<br>
+ addPass(EntryExitInstrumenterPass(/*PostInlining=*/true));<br>
+<br>
+ // Add scalarization of target's unsupported masked memory intrinsics pass.<br>
+ // the unsupported intrinsic will be replaced with a chain of basic blocks,<br>
+ // that stores/loads element one-by-one if the appropriate mask bit is set.<br>
+ addPass(ScalarizeMaskedMemIntrinPass());<br>
+<br>
+ // Expand reduction intrinsics into shuffle sequences if the target wants to.<br>
+ addPass(ExpandReductionsPass());<br>
+}<br>
+<br>
+/// Turn exception handling constructs into something the code generators can<br>
+/// handle.<br>
+template <typename Derived><br>
+void CodeGenPassBuilder<Derived>::addPassesToHandleExceptions(<br>
+ AddIRPass &addPass) const {<br>
+ const MCAsmInfo *MCAI = TM.getMCAsmInfo();<br>
+ assert(MCAI && "No MCAsmInfo");<br>
+ switch (MCAI->getExceptionHandlingType()) {<br>
+ case ExceptionHandling::SjLj:<br>
+ // SjLj piggy-backs on dwarf for this bit. The cleanups done apply to both<br>
+ // Dwarf EH prepare needs to be run after SjLj prepare. Otherwise,<br>
+ // catch info can get misplaced when a selector ends up more than one block<br>
+ // removed from the parent invoke(s). This could happen when a landing<br>
+ // pad is shared by multiple invokes and is also a target of a normal<br>
+ // edge from elsewhere.<br>
+ addPass(SjLjEHPreparePass());<br>
+ LLVM_FALLTHROUGH;<br>
+ case ExceptionHandling::DwarfCFI:<br>
+ case ExceptionHandling::ARM:<br>
+ addPass(DwarfEHPass());<br>
+ break;<br>
+ case ExceptionHandling::WinEH:<br>
+ // We support using both GCC-style and MSVC-style exceptions on Windows, so<br>
+ // add both preparation passes. Each pass will only actually run if it<br>
+ // recognizes the personality function.<br>
+ addPass(WinEHPass());<br>
+ addPass(DwarfEHPass());<br>
+ break;<br>
+ case ExceptionHandling::Wasm:<br>
+ // Wasm EH uses Windows EH instructions, but it does not need to demote PHIs<br>
+ // on catchpads and cleanuppads because it does not outline them into<br>
+ // funclets. Catchswitch blocks are not lowered in SelectionDAG, so we<br>
+ // should remove PHIs there.<br>
+ addPass(WinEHPass(/*DemoteCatchSwitchPHIOnly=*/false));<br>
+ addPass(WasmEHPass());<br>
+ break;<br>
+ case ExceptionHandling::None:<br>
+ addPass(LowerInvokePass());<br>
+<br>
+ // The lower invoke pass may create unreachable code. Remove it.<br>
+ addPass(UnreachableBlockElimPass());<br>
+ break;<br>
+ }<br>
+}<br>
+<br>
+/// Add pass to prepare the LLVM IR for code generation. This should be done<br>
+/// before exception handling preparation passes.<br>
+template <typename Derived><br>
+void CodeGenPassBuilder<Derived>::addCodeGenPrepare(AddIRPass &addPass) const {<br>
+ if (getOptLevel() != CodeGenOpt::None && !Opt.DisableCodeGenPreparePass)<br>
+ addPass(CodeGenPreparePass());<br>
+ // TODO: Default ctor'd RewriteSymbolPass is no-op.<br>
+ // addPass(RewriteSymbolPass());<br>
+}<br>
+<br>
+/// Add common passes that perform LLVM IR to IR transforms in preparation for<br>
+/// instruction selection.<br>
+template <typename Derived><br>
+void CodeGenPassBuilder<Derived>::addISelPrepare(AddIRPass &addPass) const {<br>
+ derived().addPreISel(addPass);<br>
+<br>
+ // Add both the safe stack and the stack protection passes: each of them will<br>
+ // only protect functions that have corresponding attributes.<br>
+ addPass(SafeStackPass());<br>
+ addPass(StackProtectorPass());<br>
+<br>
+ if (Opt.PrintISelInput)<br>
+ addPass(PrintFunctionPass(dbgs(),<br>
+ "\n\n*** Final LLVM Code input to ISel ***\n"));<br>
+<br>
+ // All passes which modify the LLVM IR are now complete; run the verifier<br>
+ // to ensure that the IR is valid.<br>
+ if (!Opt.DisableVerify)<br>
+ addPass(VerifierPass());<br>
+}<br>
+<br>
+template <typename Derived><br>
+Expected<typename CodeGenPassBuilder<Derived>::AddMachinePass><br>
+CodeGenPassBuilder<Derived>::addCoreISelPasses() const {<br>
+ // Enable FastISel with -fast-isel, but allow that to be overridden.<br>
+ TM.setO0WantsFastISel(Opt.EnableFastISelOption.getValueOr(true));<br>
+<br>
+ // Determine an instruction selector.<br>
+ enum class SelectorType { SelectionDAG, FastISel, GlobalISel };<br>
+ SelectorType Selector;<br>
+<br>
+ if (Opt.EnableFastISelOption && *Opt.EnableFastISelOption == true)<br>
+ Selector = SelectorType::FastISel;<br>
+ else if ((Opt.EnableGlobalISelOption &&<br>
+ *Opt.EnableGlobalISelOption == true) ||<br>
+ (TM.Options.EnableGlobalISel &&<br>
+ (!Opt.EnableGlobalISelOption ||<br>
+ *Opt.EnableGlobalISelOption == false)))<br>
+ Selector = SelectorType::GlobalISel;<br>
+ else if (TM.getOptLevel() == CodeGenOpt::None && TM.getO0WantsFastISel())<br>
+ Selector = SelectorType::FastISel;<br>
+ else<br>
+ Selector = SelectorType::SelectionDAG;<br>
+<br>
+ // Set consistently TM.Options.EnableFastISel and EnableGlobalISel.<br>
+ if (Selector == SelectorType::FastISel) {<br>
+ TM.setFastISel(true);<br>
+ TM.setGlobalISel(false);<br>
+ } else if (Selector == SelectorType::GlobalISel) {<br>
+ TM.setFastISel(false);<br>
+ TM.setGlobalISel(true);<br>
+ }<br>
+<br>
+ AddMachinePass addPass(Opt.DebugPM, Opt.RequiresCodeGenSCCOrder,<br>
+ *Opt.VerifyMachineCode);<br>
+<br>
+ // Add instruction selector passes.<br>
+ if (Selector == SelectorType::GlobalISel) {<br>
+ if (auto Err = derived().addIRTranslator(addPass))<br>
+ return std::move(Err);<br>
+<br>
+ derived().addPreLegalizeMachineIR(addPass);<br>
+<br>
+ if (auto Err = derived().addLegalizeMachineIR(addPass))<br>
+ return std::move(Err);<br>
+<br>
+ // Before running the register bank selector, ask the target if it<br>
+ // wants to run some passes.<br>
+ derived().addPreRegBankSelect(addPass);<br>
+<br>
+ if (auto Err = derived().addRegBankSelect(addPass))<br>
+ return std::move(Err);<br>
+<br>
+ derived().addPreGlobalInstructionSelect(addPass);<br>
+<br>
+ if (auto Err = derived().addGlobalInstructionSelect(addPass))<br>
+ return std::move(Err);<br>
+<br>
+ // Pass to reset the MachineFunction if the ISel failed.<br>
+ addPass(ResetMachineFunctionPass(reportDiagnosticWhenGlobalISelFallback(),<br>
+ isGlobalISelAbortEnabled()));<br>
+<br>
+ // Provide a fallback path when we do not want to abort on<br>
+ // not-yet-supported input.<br>
+ if (!isGlobalISelAbortEnabled()) {<br>
+ if (auto Err = derived().addInstSelector(addPass))<br>
+ return std::move(Err);<br>
+ }<br>
+<br>
+ } else if (auto Err = derived().addInstSelector(addPass))<br>
+ return std::move(Err);<br>
+<br>
+ // Expand pseudo-instructions emitted by ISel. Don't run the verifier before<br>
+ // FinalizeISel.<br>
+ addPass(FinalizeISelPass());<br>
+<br>
+ return addPass;<br>
+}<br>
+<br>
+/// Add the complete set of target-independent postISel code generator passes.<br>
+///<br>
+/// This can be read as the standard order of major LLVM CodeGen stages. Stages<br>
+/// with nontrivial configuration or multiple passes are broken out below in<br>
+/// add%Stage routines.<br>
+///<br>
+/// Any CodeGenPassBuilder<Derived>::addXX routine may be overriden by the<br>
+/// Target. The addPre/Post methods with empty header implementations allow<br>
+/// injecting target-specific fixups just before or after major stages.<br>
+/// Additionally, targets have the flexibility to change pass order within a<br>
+/// stage by overriding default implementation of add%Stage routines below. Each<br>
+/// technique has maintainability tradeoffs because alternate pass orders are<br>
+/// not well supported. addPre/Post works better if the target pass is easily<br>
+/// tied to a common pass. But if it has subtle dependencies on multiple passes,<br>
+/// the target should override the stage instead.<br>
+template <typename Derived><br>
+Error CodeGenPassBuilder<Derived>::addMachinePasses(<br>
+ AddMachinePass &addPass) const {<br>
+ // Add passes that optimize machine instructions in SSA form.<br>
+ if (getOptLevel() != CodeGenOpt::None) {<br>
+ derived().addMachineSSAOptimization(addPass);<br>
+ } else {<br>
+ // If the target requests it, assign local variables to stack slots relative<br>
+ // to one another and simplify frame index references where possible.<br>
+ addPass(LocalStackSlotPass());<br>
+ }<br>
+<br>
+ if (TM.Options.EnableIPRA)<br>
+ addPass(RegUsageInfoPropagationPass());<br>
+<br>
+ // Run pre-ra passes.<br>
+ derived().addPreRegAlloc(addPass);<br>
+<br>
+ // Run register allocation and passes that are tightly coupled with it,<br>
+ // including phi elimination and scheduling.<br>
+ if (*Opt.OptimizeRegAlloc) {<br>
+ derived().addOptimizedRegAlloc(addPass);<br>
+ } else {<br>
+ if (auto Err = derived().addFastRegAlloc(addPass))<br>
+ return Err;<br>
+ }<br>
+<br>
+ // Run post-ra passes.<br>
+ derived().addPostRegAlloc(addPass);<br>
+<br>
+ // Insert prolog/epilog code. Eliminate abstract frame index references...<br>
+ if (getOptLevel() != CodeGenOpt::None) {<br>
+ addPass(PostRAMachineSinkingPass());<br>
+ addPass(ShrinkWrapPass());<br>
+ }<br>
+<br>
+ addPass(PrologEpilogInserterPass());<br>
+<br>
+ /// Add passes that optimize machine instructions after register allocation.<br>
+ if (getOptLevel() != CodeGenOpt::None)<br>
+ derived().addMachineLateOptimization(addPass);<br>
+<br>
+ // Expand pseudo instructions before second scheduling pass.<br>
+ addPass(ExpandPostRAPseudosPass());<br>
+<br>
+ // Run pre-sched2 passes.<br>
+ derived().addPreSched2(addPass);<br>
+<br>
+ if (Opt.EnableImplicitNullChecksPass)<br>
+ addPass(ImplicitNullChecksPass());<br>
+<br>
+ // Second pass scheduler.<br>
+ // Let Target optionally insert this pass by itself at some other point.<br>
+ if (getOptLevel() != CodeGenOpt::None &&<br>
+ !TM.targetSchedulesPostRAScheduling()) {<br>
+ if (Opt.EnablePostMachineSchedulerPass)<br>
+ addPass(PostMachineSchedulerPass());<br>
+ else<br>
+ addPass(PostRASchedulerPass());<br>
+ }<br>
+<br>
+ // GC<br>
+ derived().addGCPasses(addPass);<br>
+<br>
+ // Basic block placement.<br>
+ if (getOptLevel() != CodeGenOpt::None)<br>
+ derived().addBlockPlacement(addPass);<br>
+<br>
+ // Insert before XRay Instrumentation.<br>
+ addPass(FEntryInserterPass());<br>
+<br>
+ addPass(XRayInstrumentationPass());<br>
+ addPass(PatchableFunctionPass());<br>
+<br>
+ derived().addPreEmitPass(addPass);<br>
+<br>
+ if (TM.Options.EnableIPRA) {<br>
+ // Collect register usage information and produce a register mask of<br>
+ // clobbered registers, to be used to optimize call sites.<br>
+ addPass(RegUsageInfoCollectorPass());<br>
+ }<br>
+<br>
+ addPass(FuncletLayoutPass());<br>
+<br>
+ addPass(StackMapLivenessPass());<br>
+ addPass(LiveDebugValuesPass());<br>
+<br>
+ if (TM.Options.EnableMachineOutliner && getOptLevel() != CodeGenOpt::None &&<br>
+ Opt.EnableMachineOutliner != RunOutliner::NeverOutline) {<br>
+ bool RunOnAllFunctions =<br>
+ (Opt.EnableMachineOutliner == RunOutliner::AlwaysOutline);<br>
+ bool AddOutliner = RunOnAllFunctions || TM.Options.SupportsDefaultOutlining;<br>
+ if (AddOutliner)<br>
+ addPass(MachineOutlinerPass(RunOnAllFunctions));<br>
+ }<br>
+<br>
+ // Add passes that directly emit MI after all other MI passes.<br>
+ derived().addPreEmitPass2(addPass);<br>
+<br>
+ return Error::success();<br>
+}<br>
+<br>
+/// Add passes that optimize machine instructions in SSA form.<br>
+template <typename Derived><br>
+void CodeGenPassBuilder<Derived>::addMachineSSAOptimization(<br>
+ AddMachinePass &addPass) const {<br>
+ // Pre-ra tail duplication.<br>
+ addPass(EarlyTailDuplicatePass());<br>
+<br>
+ // Optimize PHIs before DCE: removing dead PHI cycles may make more<br>
+ // instructions dead.<br>
+ addPass(OptimizePHIsPass());<br>
+<br>
+ // This pass merges large allocas. StackSlotColoring is a<br>
diff erent pass<br>
+ // which merges spill slots.<br>
+ addPass(StackColoringPass());<br>
+<br>
+ // If the target requests it, assign local variables to stack slots relative<br>
+ // to one another and simplify frame index references where possible.<br>
+ addPass(LocalStackSlotPass());<br>
+<br>
+ // With optimization, dead code should already be eliminated. However<br>
+ // there is one known exception: lowered code for arguments that are only<br>
+ // used by tail calls, where the tail calls reuse the incoming stack<br>
+ // arguments directly (see t11 in test/CodeGen/X86/sibcall.ll).<br>
+ addPass(DeadMachineInstructionElimPass());<br>
+<br>
+ // Allow targets to insert passes that improve instruction level parallelism,<br>
+ // like if-conversion. Such passes will typically need dominator trees and<br>
+ // loop info, just like LICM and CSE below.<br>
+ derived().addILPOpts(addPass);<br>
+<br>
+ addPass(EarlyMachineLICMPass());<br>
+ addPass(MachineCSEPass());<br>
+<br>
+ addPass(MachineSinkingPass());<br>
+<br>
+ addPass(PeepholeOptimizerPass());<br>
+ // Clean-up the dead code that may have been generated by peephole<br>
+ // rewriting.<br>
+ addPass(DeadMachineInstructionElimPass());<br>
+}<br>
+<br>
+//===---------------------------------------------------------------------===//<br>
+/// Register Allocation Pass Configuration<br>
+//===---------------------------------------------------------------------===//<br>
+<br>
+/// Instantiate the default register allocator pass for this target for either<br>
+/// the optimized or unoptimized allocation path. This will be added to the pass<br>
+/// manager by addFastRegAlloc in the unoptimized case or addOptimizedRegAlloc<br>
+/// in the optimized case.<br>
+///<br>
+/// A target that uses the standard regalloc pass order for fast or optimized<br>
+/// allocation may still override this for per-target regalloc<br>
+/// selection. But -regalloc=... always takes precedence.<br>
+template <typename Derived><br>
+void CodeGenPassBuilder<Derived>::addTargetRegisterAllocator(<br>
+ AddMachinePass &addPass, bool Optimized) const {<br>
+ if (Optimized)<br>
+ addPass(RAGreedyPass());<br>
+ else<br>
+ addPass(RAFastPass());<br>
+}<br>
+<br>
+/// Find and instantiate the register allocation pass requested by this target<br>
+/// at the current optimization level. Different register allocators are<br>
+/// defined as separate passes because they may require<br>
diff erent analysis.<br>
+template <typename Derived><br>
+void CodeGenPassBuilder<Derived>::addRegAllocPass(AddMachinePass &addPass,<br>
+ bool Optimized) const {<br>
+ switch (Opt.RegAlloc) {<br>
+ case RegAllocType::Default:<br>
+ // With no -regalloc= override, ask the target for a regalloc pass.<br>
+ derived().addTargetRegisterAllocator(addPass, Optimized);<br>
+ break;<br>
+ case RegAllocType::Basic:<br>
+ addPass(RABasicPass());<br>
+ break;<br>
+ case RegAllocType::Fast:<br>
+ addPass(RAFastPass());<br>
+ break;<br>
+ case RegAllocType::Greedy:<br>
+ addPass(RAGreedyPass());<br>
+ break;<br>
+ case RegAllocType::PBQP:<br>
+ addPass(RAPBQPPass());<br>
+ break;<br>
+ default:<br>
+ llvm_unreachable("unknonwn register allocator type");<br>
+ }<br>
+}<br>
+<br>
+template <typename Derived><br>
+Error CodeGenPassBuilder<Derived>::addRegAssignmentFast(<br>
+ AddMachinePass &addPass) const {<br>
+ if (Opt.RegAlloc != RegAllocType::Default &&<br>
+ Opt.RegAlloc != RegAllocType::Fast)<br>
+ return make_error<StringError>(<br>
+ "Must use fast (default) register allocator for unoptimized regalloc.",<br>
+ inconvertibleErrorCode());<br>
+<br>
+ addRegAllocPass(addPass, false);<br>
+ return Error::success();<br>
+}<br>
+<br>
+template <typename Derived><br>
+Error CodeGenPassBuilder<Derived>::addRegAssignmentOptimized(<br>
+ AddMachinePass &addPass) const {<br>
+ // Add the selected register allocation pass.<br>
+ addRegAllocPass(addPass, true);<br>
+<br>
+ // Allow targets to change the register assignments before rewriting.<br>
+ derived().addPreRewrite(addPass);<br>
+<br>
+ // Finally rewrite virtual registers.<br>
+ addPass(VirtRegRewriterPass());<br>
+ // Perform stack slot coloring and post-ra machine LICM.<br>
+ //<br>
+ // FIXME: Re-enable coloring with register when it's capable of adding<br>
+ // kill markers.<br>
+ addPass(StackSlotColoringPass());<br>
+<br>
+ return Error::success();<br>
+}<br>
+<br>
+/// Add the minimum set of target-independent passes that are required for<br>
+/// register allocation. No coalescing or scheduling.<br>
+template <typename Derived><br>
+Error CodeGenPassBuilder<Derived>::addFastRegAlloc(<br>
+ AddMachinePass &addPass) const {<br>
+ addPass(PHIEliminationPass());<br>
+ addPass(TwoAddressInstructionPass());<br>
+ return derived().addRegAssignmentFast(addPass);<br>
+}<br>
+<br>
+/// Add standard target-independent passes that are tightly coupled with<br>
+/// optimized register allocation, including coalescing, machine instruction<br>
+/// scheduling, and register allocation itself.<br>
+template <typename Derived><br>
+void CodeGenPassBuilder<Derived>::addOptimizedRegAlloc(<br>
+ AddMachinePass &addPass) const {<br>
+ addPass(DetectDeadLanesPass());<br>
+<br>
+ addPass(ProcessImplicitDefsPass());<br>
+<br>
+ // Edge splitting is smarter with machine loop info.<br>
+ addPass(PHIEliminationPass());<br>
+<br>
+ // Eventually, we want to run LiveIntervals before PHI elimination.<br>
+ if (Opt.EnableLiveIntervalsPass)<br>
+ addPass(LiveIntervalsPass());<br>
+<br>
+ addPass(TwoAddressInstructionPass());<br>
+ addPass(RegisterCoalescerPass());<br>
+<br>
+ // The machine scheduler may accidentally create disconnected components<br>
+ // when moving subregister definitions around, avoid this by splitting them to<br>
+ // separate vregs before. Splitting can also improve reg. allocation quality.<br>
+ addPass(RenameIndependentSubregsPass());<br>
+<br>
+ // PreRA instruction scheduling.<br>
+ addPass(MachineSchedulerPass());<br>
+<br>
+ if (derived().addRegAssignmentOptimized(addPass)) {<br>
+ // Allow targets to expand pseudo instructions depending on the choice of<br>
+ // registers before MachineCopyPropagation.<br>
+ derived().addPostRewrite(addPass);<br>
+<br>
+ // Copy propagate to forward register uses and try to eliminate COPYs that<br>
+ // were not coalesced.<br>
+ addPass(MachineCopyPropagationPass());<br>
+<br>
+ // Run post-ra machine LICM to hoist reloads / remats.<br>
+ //<br>
+ // FIXME: can this move into MachineLateOptimization?<br>
+ addPass(MachineLICMPass());<br>
+ }<br>
+}<br>
+<br>
+//===---------------------------------------------------------------------===//<br>
+/// Post RegAlloc Pass Configuration<br>
+//===---------------------------------------------------------------------===//<br>
+<br>
+/// Add passes that optimize machine instructions after register allocation.<br>
+template <typename Derived><br>
+void CodeGenPassBuilder<Derived>::addMachineLateOptimization(<br>
+ AddMachinePass &addPass) const {<br>
+ // Branch folding must be run after regalloc and prolog/epilog insertion.<br>
+ addPass(BranchFolderPass());<br>
+<br>
+ // Tail duplication.<br>
+ // Note that duplicating tail just increases code size and degrades<br>
+ // performance for targets that require Structured Control Flow.<br>
+ // In addition it can also make CFG irreducible. Thus we disable it.<br>
+ if (!TM.requiresStructuredCFG())<br>
+ addPass(TailDuplicatePass());<br>
+<br>
+ // Copy propagation.<br>
+ addPass(MachineCopyPropagationPass());<br>
+}<br>
+<br>
+/// Add standard basic block placement passes.<br>
+template <typename Derived><br>
+void CodeGenPassBuilder<Derived>::addBlockPlacement(<br>
+ AddMachinePass &addPass) const {<br>
+ addPass(MachineBlockPlacementPass());<br>
+ // Run a separate pass to collect block placement statistics.<br>
+ if (Opt.EnableMachineBlockPlacementStatsPass)<br>
+ addPass(MachineBlockPlacementStatsPass());<br>
+}<br>
+<br>
+} // namespace llvm<br>
+<br>
+#endif // LLVM_CODEGEN_CODEGENPASSBUILDER_H<br>
<br>
diff --git a/llvm/include/llvm/CodeGen/MachinePassRegistry.def b/llvm/include/llvm/CodeGen/MachinePassRegistry.def<br>
new file mode 100644<br>
index 000000000000..734bbebc76de<br>
--- /dev/null<br>
+++ b/llvm/include/llvm/CodeGen/MachinePassRegistry.def<br>
@@ -0,0 +1,195 @@<br>
+//===- MachinePassRegistry.def - Registry of passes -------------*- C++ -*-===//<br>
+//<br>
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.<br>
+// See <a href="https://llvm.org/LICENSE.txt" rel="noreferrer" target="_blank">https://llvm.org/LICENSE.txt</a> for license information.<br>
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// This file is used as the registry of passes that are for target-independent<br>
+// code generator.<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+<br>
+// NOTE: NO INCLUDE GUARD DESIRED!<br>
+<br>
+#ifndef MODULE_ANALYSIS<br>
+#define MODULE_ANALYSIS(NAME, PASS_NAME, CONSTRUCTOR)<br>
+#endif<br>
+MODULE_ANALYSIS("pass-instrumentation", PassInstrumentationAnalysis, (PIC))<br>
+#undef MODULE_ANALYSIS<br>
+<br>
+#ifndef MODULE_PASS<br>
+#define MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR)<br>
+#endif<br>
+MODULE_PASS("pre-isel-intrinsic-lowering", PreISelIntrinsicLoweringPass, ())<br>
+#undef MODULE_PASS<br>
+<br>
+#ifndef FUNCTION_ANALYSIS<br>
+#define FUNCTION_ANALYSIS(NAME, PASS_NAME, CONSTRUCTOR)<br>
+#endif<br>
+FUNCTION_ANALYSIS("pass-instrumentation", PassInstrumentationAnalysis, (PIC))<br>
+FUNCTION_ANALYSIS("targetir", TargetIRAnalysis, (std::move(TM.getTargetIRAnalysis())))<br>
+#undef FUNCTION_ANALYSIS<br>
+<br>
+#ifndef FUNCTION_PASS<br>
+#define FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)<br>
+#endif<br>
+FUNCTION_PASS("mergeicmps", MergeICmpsPass, ())<br>
+FUNCTION_PASS("lower-constant-intrinsics", LowerConstantIntrinsicsPass, ())<br>
+FUNCTION_PASS("unreachableblockelim", UnreachableBlockElimPass, ())<br>
+FUNCTION_PASS("consthoist", ConstantHoistingPass, ())<br>
+FUNCTION_PASS("partially-inline-libcalls", PartiallyInlineLibCallsPass, ())<br>
+FUNCTION_PASS("ee-instrument", EntryExitInstrumenterPass, (false))<br>
+FUNCTION_PASS("post-inline-ee-instrument", EntryExitInstrumenterPass, (true))<br>
+FUNCTION_PASS("expand-reductions", ExpandReductionsPass, ())<br>
+FUNCTION_PASS("lowerinvoke", LowerInvokePass, ())<br>
+FUNCTION_PASS("verify", VerifierPass, ())<br>
+#undef FUNCTION_PASS<br>
+<br>
+#ifndef LOOP_PASS<br>
+#define LOOP_PASS(NAME, PASS_NAME, CONSTRUCTOR)<br>
+#endif<br>
+LOOP_PASS("loop-reduce", LoopStrengthReducePass, ())<br>
+#undef LOOP_PASS<br>
+<br>
+#ifndef MACHINE_MODULE_PASS<br>
+#define MACHINE_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR)<br>
+#endif<br>
+#undef MACHINE_MODULE_PASS<br>
+<br>
+#ifndef MACHINE_FUNCTION_ANALYSIS<br>
+#define MACHINE_FUNCTION_ANALYSIS(NAME, PASS_NAME, CONSTRUCTOR)<br>
+#endif<br>
+MACHINE_FUNCTION_ANALYSIS("pass-instrumentation", PassInstrumentationAnalysis, (PIC))<br>
+// LiveVariables currently requires pure SSA form.<br>
+// FIXME: Once TwoAddressInstruction pass no longer uses kill flags,<br>
+// LiveVariables can be removed completely, and LiveIntervals can be directly<br>
+// computed. (We still either need to regenerate kill flags after regalloc, or<br>
+// preferably fix the scavenger to not depend on them).<br>
+// MACHINE_FUNCTION_ANALYSIS("live-vars", LiveVariablesAnalysis())<br>
+<br>
+// MACHINE_FUNCTION_ANALYSIS("live-stacks", LiveStacksPass())<br>
+// MACHINE_FUNCTION_ANALYSIS("slot-indexes", SlotIndexesAnalysis())<br>
+// MACHINE_FUNCTION_ANALYSIS("edge-bundles", EdgeBundlesAnalysis())<br>
+// MACHINE_FUNCTION_ANALYSIS("lazy-machine-bfi", LazyMachineBlockFrequencyInfoAnalysis())<br>
+// MACHINE_FUNCTION_ANALYSIS("machine-bfi", MachineBlockFrequencyInfoAnalysis())<br>
+// MACHINE_FUNCTION_ANALYSIS("machine-loops", MachineLoopInfoAnalysis())<br>
+// MACHINE_FUNCTION_ANALYSIS("machine-dom-frontier", MachineDominanceFrontierAnalysis())<br>
+// MACHINE_FUNCTION_ANALYSIS("machine-dom-tree", MachineDominatorTreeAnalysis())<br>
+// MACHINE_FUNCTION_ANALYSIS("machine-ore", MachineOptimizationRemarkEmitterPassAnalysis())<br>
+// MACHINE_FUNCTION_ANALYSIS("machine-post-dom-tree", MachinePostDominatorTreeAnalysis())<br>
+// MACHINE_FUNCTION_ANALYSIS("machine-region-info", MachineRegionInfoPassAnalysis())<br>
+// MACHINE_FUNCTION_ANALYSIS("machine-trace-metrics", MachineTraceMetricsAnalysis())<br>
+// MACHINE_FUNCTION_ANALYSIS("reaching-def", ReachingDefAnalysisAnalysis())<br>
+// MACHINE_FUNCTION_ANALYSIS("live-reg-matrix", LiveRegMatrixAnalysis())<br>
+// MACHINE_FUNCTION_ANALYSIS("gc-analysis", GCMachineCodeAnalysisPass())<br>
+#undef MACHINE_FUNCTION_ANALYSIS<br>
+<br>
+#ifndef MACHINE_FUNCTION_PASS<br>
+#define MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)<br>
+#endif<br>
+MACHINE_FUNCTION_PASS("mir-printer", PrintMIRPass, ())<br>
+#undef MACHINE_FUNCTION_PASS<br>
+<br>
+// After a pass is converted to new pass manager, its entry should be moved from<br>
+// dummy table to the normal one. For example, for a machine function pass,<br>
+// DUMMY_MACHINE_FUNCTION_PASS to MACHINE_FUNCTION_PASS.<br>
+<br>
+#ifndef DUMMY_FUNCTION_PASS<br>
+#define DUMMY_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)<br>
+#endif<br>
+DUMMY_FUNCTION_PASS("expandmemcmp", ExpandMemCmpPass, ())<br>
+DUMMY_FUNCTION_PASS("gc-lowering", GCLoweringPass, ())<br>
+DUMMY_FUNCTION_PASS("shadow-stack-gc-lowering", ShadowStackGCLoweringPass, ())<br>
+DUMMY_FUNCTION_PASS("scalarize-masked-mem-intrin", ScalarizeMaskedMemIntrinPass, ())<br>
+DUMMY_FUNCTION_PASS("sjljehprepare", SjLjEHPreparePass, ())<br>
+DUMMY_FUNCTION_PASS("dwarfehprepare", DwarfEHPass, ())<br>
+DUMMY_FUNCTION_PASS("winehprepare", WinEHPass, ())<br>
+DUMMY_FUNCTION_PASS("wasmehprepare", WasmEHPass, ())<br>
+DUMMY_FUNCTION_PASS("codegenprepare", CodeGenPreparePass, ())<br>
+DUMMY_FUNCTION_PASS("safe-stack", SafeStackPass, ())<br>
+DUMMY_FUNCTION_PASS("stack-protector", StackProtectorPass, ())<br>
+DUMMY_FUNCTION_PASS("atomic-expand", AtomicExpandPass, ())<br>
+DUMMY_FUNCTION_PASS("interleaved-access", InterleavedAccessPass, ())<br>
+DUMMY_FUNCTION_PASS("indirectbr-expand", IndirectBrExpandPass, ())<br>
+DUMMY_FUNCTION_PASS("cfguard-dispatch", CFGuardDispatchPass, ())<br>
+DUMMY_FUNCTION_PASS("cfguard-check", CFGuardCheckPass, ())<br>
+DUMMY_FUNCTION_PASS("gc-info-printer", GCInfoPrinterPass, ())<br>
+#undef DUMMY_FUNCTION_PASS<br>
+<br>
+#ifndef DUMMY_MODULE_PASS<br>
+#define DUMMY_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR)<br>
+#endif<br>
+DUMMY_MODULE_PASS("lower-emutls", LowerEmuTLSPass, ())<br>
+#undef DUMMY_MODULE_PASS<br>
+<br>
+#ifndef DUMMY_MACHINE_MODULE_PASS<br>
+#define DUMMY_MACHINE_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR)<br>
+#endif<br>
+DUMMY_MACHINE_MODULE_PASS("machine-outliner", MachineOutlinerPass, ())<br>
+#undef DUMMY_MACHINE_MODULE_PASS<br>
+<br>
+#ifndef DUMMY_MACHINE_FUNCTION_PASS<br>
+#define DUMMY_MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR)<br>
+#endif<br>
+DUMMY_MACHINE_FUNCTION_PASS("free-machine-function", FreeMachineFunctionPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("finalize-isel", FinalizeISelPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("localstackalloc", LocalStackSlotPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("shrink-wrap", ShrinkWrapPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("prologepilog", PrologEpilogInserterPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("postrapseudos", ExpandPostRAPseudosPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("implicit-null-checks", ImplicitNullChecksPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("postmisched", PostMachineSchedulerPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("machine-scheduler", MachineSchedulerPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("machine-cp", MachineCopyPropagationPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("post-RA-sched", PostRASchedulerPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("fentry-insert", FEntryInserterPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("xray-instrumentation", XRayInstrumentationPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("patchable-function", PatchableFunctionPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("reg-usage-propagation", RegUsageInfoPropagationPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("reg-usage-collector", RegUsageInfoCollectorPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("funclet-layout", FuncletLayoutPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("stackmap-liveness", StackMapLivenessPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("livedebugvalues", LiveDebugValuesPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("early-tailduplication", EarlyTailDuplicatePass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("opt-phis", OptimizePHIsPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("stack-coloring", StackColoringPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("dead-mi-elimination", DeadMachineInstructionElimPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("early-machinelicm", EarlyMachineLICMPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("machinelicm", MachineLICMPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("machine-cse", MachineCSEPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("machine-sink", MachineSinkingPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("postra-machine-sink", PostRAMachineSinkingPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("peephole-opt", PeepholeOptimizerPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("regalloc", RegAllocPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("virtregrewriter", VirtRegRewriterPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("stack-slot-coloring", StackSlotColoringPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("phi-node-elimination", PHIEliminationPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("twoaddressinstruction", TwoAddressInstructionPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("detect-dead-lanes", DetectDeadLanesPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("processimpdefs", ProcessImplicitDefsPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("liveintervals", LiveIntervalsPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("simple-register-coalescing", RegisterCoalescerPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("rename-independent-subregs", RenameIndependentSubregsPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("branch-folder", BranchFolderPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("tailduplication", TailDuplicatePass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("block-placement", MachineBlockPlacementPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("block-placement-stats", MachineBlockPlacementStatsPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("early-ifcvt", EarlyIfConverterPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("machine-combiner", MachineCombinerPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("lrshrink", LiveRangeShrinkPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("break-false-deps", BreakFalseDepsPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("cfi-instr-inserter", CFIInstrInserterPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("cfguard-longjmp", CFGuardLongjmpPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("ra-basic", RABasicPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("ra-fast", RAFastPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("ra-greedy", RAGreedyPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("ra-pbqp", RAPBQPPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("legalizer", LegalizerPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("irtranslator", IRTranslatorPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("regbankselect", RegBankSelectPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("instruction-select", InstructionSelectPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("reset-machine-function", ResetMachineFunctionPass, ())<br>
+DUMMY_MACHINE_FUNCTION_PASS("machineverifier", MachineVerifierPass, ())<br>
+#undef DUMMY_MACHINE_FUNCTION_PASS<br>
<br>
diff --git a/llvm/include/llvm/Passes/StandardInstrumentations.h b/llvm/include/llvm/Passes/StandardInstrumentations.h<br>
index 76e217c89974..457eae26fd47 100644<br>
--- a/llvm/include/llvm/Passes/StandardInstrumentations.h<br>
+++ b/llvm/include/llvm/Passes/StandardInstrumentations.h<br>
@@ -28,6 +28,7 @@<br>
<br>
namespace llvm {<br>
<br>
+class LLVMTargetMachine;<br>
class Module;<br>
class Function;<br>
<br>
@@ -140,6 +141,10 @@ class StandardInstrumentations {<br>
<br>
TimePassesHandler &getTimePasses() { return TimePasses; }<br>
};<br>
+<br>
+void registerCodeGenCallback(PassInstrumentationCallbacks &PIC,<br>
+ LLVMTargetMachine &);<br>
+<br>
} // namespace llvm<br>
<br>
#endif<br>
<br>
diff --git a/llvm/include/llvm/Target/TargetMachine.h b/llvm/include/llvm/Target/TargetMachine.h<br>
index 2a422341fdc8..c7673d3e74e4 100644<br>
--- a/llvm/include/llvm/Target/TargetMachine.h<br>
+++ b/llvm/include/llvm/Target/TargetMachine.h<br>
@@ -15,9 +15,12 @@<br>
<br>
#include "llvm/ADT/StringRef.h"<br>
#include "llvm/ADT/Triple.h"<br>
+#include "llvm/CodeGen/CGPassBuilderOption.h"<br>
+#include "llvm/CodeGen/MachinePassManager.h"<br>
#include "llvm/IR/DataLayout.h"<br>
#include "llvm/Pass.h"<br>
#include "llvm/Support/CodeGen.h"<br>
+#include "llvm/Support/Error.h"<br>
#include "llvm/Target/TargetOptions.h"<br>
#include <string><br>
<br>
@@ -367,6 +370,20 @@ class LLVMTargetMachine : public TargetMachine {<br>
bool DisableVerify = true,<br>
MachineModuleInfoWrapperPass *MMIWP = nullptr) override;<br>
<br>
+ virtual Expected<std::pair<ModulePassManager, MachineFunctionPassManager>><br>
+ buildCodeGenPipeline(raw_pwrite_stream &, raw_pwrite_stream *,<br>
+ CodeGenFileType, CGPassBuilderOption,<br>
+ MachineFunctionAnalysisManager &,<br>
+ PassInstrumentationCallbacks *) {<br>
+ return make_error<StringError>("buildCodeGenPipeline is not overriden",<br>
+ inconvertibleErrorCode());<br>
+ }<br>
+<br>
+ virtual std::pair<StringRef, bool> getPassNameFromLegacyName(StringRef) {<br>
+ llvm_unreachable(<br>
+ "getPassNameFromLegacyName parseMIRPipeline is not overriden");<br>
+ }<br>
+<br>
/// Add passes to the specified pass manager to get machine code emitted with<br>
/// the MCJIT. This method returns true if machine code is not supported. It<br>
/// fills the MCContext Ctx pointer which can be used to build custom<br>
@@ -387,6 +404,10 @@ class LLVMTargetMachine : public TargetMachine {<br>
raw_pwrite_stream *DwoOut, CodeGenFileType FileType,<br>
MCContext &Context);<br>
<br>
+ Expected<std::unique_ptr<MCStreamer>><br>
+ createMCStreamer(raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,<br>
+ CodeGenFileType FileType, MCContext &Ctx);<br>
+<br>
/// True if the target uses physical regs (as nearly all targets do). False<br>
/// for stack machines such as WebAssembly and other virtual-register<br>
/// machines. If true, all vregs must be allocated before PEI. If false, then<br>
<br>
diff --git a/llvm/lib/CodeGen/CMakeLists.txt b/llvm/lib/CodeGen/CMakeLists.txt<br>
index 617692a34792..83b3655441fe 100644<br>
--- a/llvm/lib/CodeGen/CMakeLists.txt<br>
+++ b/llvm/lib/CodeGen/CMakeLists.txt<br>
@@ -14,6 +14,7 @@ add_llvm_component_library(LLVMCodeGen<br>
CFGuardLongjmp.cpp<br>
CFIInstrInserter.cpp<br>
CodeGen.cpp<br>
+ CodeGenPassBuilder.cpp<br>
CodeGenPrepare.cpp<br>
CommandFlags.cpp<br>
CriticalAntiDepBreaker.cpp<br>
<br>
diff --git a/llvm/lib/CodeGen/CodeGenPassBuilder.cpp b/llvm/lib/CodeGen/CodeGenPassBuilder.cpp<br>
new file mode 100644<br>
index 000000000000..7f37f2069a3b<br>
--- /dev/null<br>
+++ b/llvm/lib/CodeGen/CodeGenPassBuilder.cpp<br>
@@ -0,0 +1,25 @@<br>
+//===--- CodeGenPassBuilder.cpp --------------------------------------- ---===//<br>
+//<br>
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.<br>
+// See <a href="https://llvm.org/LICENSE.txt" rel="noreferrer" target="_blank">https://llvm.org/LICENSE.txt</a> for license information.<br>
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception<br>
+//<br>
+//===----------------------------------------------------------------------===//<br>
+//<br>
+// This file defines interfaces to access the target independent code<br>
+// generation passes provided by the LLVM backend.<br>
+//<br>
+//===---------------------------------------------------------------------===//<br>
+<br>
+#include "llvm/CodeGen/CodeGenPassBuilder.h"<br>
+<br>
+using namespace llvm;<br>
+<br>
+namespace llvm {<br>
+#define DUMMY_MACHINE_MODULE_PASS(NAME, PASS_NAME, CONSTRUCTOR) \<br>
+ AnalysisKey PASS_NAME::Key;<br>
+#include "llvm/CodeGen/MachinePassRegistry.def"<br>
+#define DUMMY_MACHINE_FUNCTION_PASS(NAME, PASS_NAME, CONSTRUCTOR) \<br>
+ AnalysisKey PASS_NAME::Key;<br>
+#include "llvm/CodeGen/MachinePassRegistry.def"<br>
+} // namespace llvm<br>
<br>
diff --git a/llvm/lib/CodeGen/LLVMTargetMachine.cpp b/llvm/lib/CodeGen/LLVMTargetMachine.cpp<br>
index e94b7ed4de03..e86f25512999 100644<br>
--- a/llvm/lib/CodeGen/LLVMTargetMachine.cpp<br>
+++ b/llvm/lib/CodeGen/LLVMTargetMachine.cpp<br>
@@ -118,6 +118,24 @@ bool LLVMTargetMachine::addAsmPrinter(PassManagerBase &PM,<br>
raw_pwrite_stream *DwoOut,<br>
CodeGenFileType FileType,<br>
MCContext &Context) {<br>
+ Expected<std::unique_ptr<MCStreamer>> MCStreamerOrErr =<br>
+ createMCStreamer(Out, DwoOut, FileType, Context);<br>
+ if (auto Err = MCStreamerOrErr.takeError())<br>
+ return true;<br>
+<br>
+ // Create the AsmPrinter, which takes ownership of AsmStreamer if successful.<br>
+ FunctionPass *Printer =<br>
+ getTarget().createAsmPrinter(*this, std::move(*MCStreamerOrErr));<br>
+ if (!Printer)<br>
+ return true;<br>
+<br>
+ PM.add(Printer);<br>
+ return false;<br>
+}<br>
+<br>
+Expected<std::unique_ptr<MCStreamer>> LLVMTargetMachine::createMCStreamer(<br>
+ raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut, CodeGenFileType FileType,<br>
+ MCContext &Context) {<br>
if (Options.MCOptions.MCSaveTempLabels)<br>
Context.setAllowTemporaryLabels(false);<br>
<br>
@@ -152,10 +170,14 @@ bool LLVMTargetMachine::addAsmPrinter(PassManagerBase &PM,<br>
// Create the code emitter for the target if it exists. If not, .o file<br>
// emission fails.<br>
MCCodeEmitter *MCE = getTarget().createMCCodeEmitter(MII, MRI, Context);<br>
+ if (!MCE)<br>
+ return make_error<StringError>("createMCCodeEmitter failed",<br>
+ inconvertibleErrorCode());<br>
MCAsmBackend *MAB =<br>
getTarget().createMCAsmBackend(STI, MRI, Options.MCOptions);<br>
- if (!MCE || !MAB)<br>
- return true;<br>
+ if (!MAB)<br>
+ return make_error<StringError>("createMCAsmBackend failed",<br>
+ inconvertibleErrorCode());<br>
<br>
Triple T(getTargetTriple().str());<br>
AsmStreamer.reset(getTarget().createMCObjectStreamer(<br>
@@ -174,14 +196,7 @@ bool LLVMTargetMachine::addAsmPrinter(PassManagerBase &PM,<br>
break;<br>
}<br>
<br>
- // Create the AsmPrinter, which takes ownership of AsmStreamer if successful.<br>
- FunctionPass *Printer =<br>
- getTarget().createAsmPrinter(*this, std::move(AsmStreamer));<br>
- if (!Printer)<br>
- return true;<br>
-<br>
- PM.add(Printer);<br>
- return false;<br>
+ return std::move(AsmStreamer);<br>
}<br>
<br>
bool LLVMTargetMachine::addPassesToEmitFile(<br>
<br>
diff --git a/llvm/lib/CodeGen/TargetPassConfig.cpp b/llvm/lib/CodeGen/TargetPassConfig.cpp<br>
index 19db8eb480ca..03a567e3d443 100644<br>
--- a/llvm/lib/CodeGen/TargetPassConfig.cpp<br>
+++ b/llvm/lib/CodeGen/TargetPassConfig.cpp<br>
@@ -22,6 +22,7 @@<br>
#include "llvm/Analysis/ScopedNoAliasAA.h"<br>
#include "llvm/Analysis/TargetTransformInfo.h"<br>
#include "llvm/Analysis/TypeBasedAliasAnalysis.h"<br>
+#include "llvm/CodeGen/CGPassBuilderOption.h"<br>
#include "llvm/CodeGen/CSEConfigBase.h"<br>
#include "llvm/CodeGen/MachineFunctionPass.h"<br>
#include "llvm/CodeGen/MachinePassRegistry.h"<br>
@@ -29,11 +30,13 @@<br>
#include "llvm/CodeGen/RegAllocRegistry.h"<br>
#include "llvm/IR/IRPrintingPasses.h"<br>
#include "llvm/IR/LegacyPassManager.h"<br>
+#include "llvm/IR/PassInstrumentation.h"<br>
#include "llvm/IR/Verifier.h"<br>
#include "llvm/InitializePasses.h"<br>
#include "llvm/MC/MCAsmInfo.h"<br>
#include "llvm/MC/MCTargetOptions.h"<br>
#include "llvm/Pass.h"<br>
+#include "llvm/Passes/StandardInstrumentations.h"<br>
#include "llvm/Support/CodeGen.h"<br>
#include "llvm/Support/CommandLine.h"<br>
#include "llvm/Support/Compiler.h"<br>
@@ -120,16 +123,17 @@ static cl::opt<cl::boolOrDefault> DebugifyAndStripAll(<br>
"Debugify MIR before and Strip debug after "<br>
"each pass except those known to be unsafe when debug info is present"),<br>
cl::ZeroOrMore);<br>
-enum RunOutliner { AlwaysOutline, NeverOutline, TargetDefault };<br>
+<br>
// Enable or disable the MachineOutliner.<br>
static cl::opt<RunOutliner> EnableMachineOutliner(<br>
"enable-machine-outliner", cl::desc("Enable the machine outliner"),<br>
- cl::Hidden, cl::ValueOptional, cl::init(TargetDefault),<br>
- cl::values(clEnumValN(AlwaysOutline, "always",<br>
+ cl::Hidden, cl::ValueOptional, cl::init(RunOutliner::TargetDefault),<br>
+ cl::values(clEnumValN(RunOutliner::AlwaysOutline, "always",<br>
"Run on all functions guaranteed to be beneficial"),<br>
- clEnumValN(NeverOutline, "never", "Disable all outlining"),<br>
+ clEnumValN(RunOutliner::NeverOutline, "never",<br>
+ "Disable all outlining"),<br>
// Sentinel value for unspecified option.<br>
- clEnumValN(AlwaysOutline, "", "")));<br>
+ clEnumValN(RunOutliner::AlwaysOutline, "", "")));<br>
// Enable or disable FastISel. Both options are needed, because<br>
// FastISel is enabled by default with -fast, and we wish to be<br>
// able to enable or disable fast-isel independently from -O0.<br>
@@ -172,7 +176,6 @@ static cl::opt<bool> EarlyLiveIntervals("early-live-intervals", cl::Hidden,<br>
cl::desc("Run live interval analysis earlier in the pipeline"));<br>
<br>
// Experimental option to use CFL-AA in codegen<br>
-enum class CFLAAType { None, Steensgaard, Andersen, Both };<br>
static cl::opt<CFLAAType> UseCFLAA(<br>
"use-cfl-aa-in-codegen", cl::init(CFLAAType::None), cl::Hidden,<br>
cl::desc("Enable the new, experimental CFL alias analysis in CodeGen"),<br>
@@ -404,6 +407,143 @@ void TargetPassConfig::setStartStopPasses() {<br>
Started = (StartAfter == nullptr) && (StartBefore == nullptr);<br>
}<br>
<br>
+CGPassBuilderOption llvm::getCGPassBuilderOption() {<br>
+ CGPassBuilderOption Opt;<br>
+<br>
+#define SET_OPTION(Option) \<br>
+ if (Option.getNumOccurrences()) \<br>
+ Opt.Option = Option;<br>
+<br>
+ SET_OPTION(EnableFastISelOption)<br>
+ SET_OPTION(EnableGlobalISelAbort)<br>
+ SET_OPTION(EnableGlobalISelOption)<br>
+ SET_OPTION(EnableIPRA)<br>
+ SET_OPTION(OptimizeRegAlloc)<br>
+ SET_OPTION(VerifyMachineCode)<br>
+<br>
+ Opt.EnableMachineOutliner = EnableMachineOutliner;<br>
+ Opt.UseCFLAA = UseCFLAA;<br>
+ Opt.PrintISelInput = PrintISelInput;<br>
+ Opt.PrintGCInfo = PrintGCInfo;<br>
+ Opt.EnablePostMachineSchedulerPass = MISchedPostRA;<br>
+ Opt.EnableLiveIntervalsPass = EarlyLiveIntervals;<br>
+ Opt.EnableMachineBlockPlacementStatsPass = EnableBlockPlacementStats;<br>
+ Opt.EnableImplicitNullChecksPass = EnableImplicitNullChecks;<br>
+ Opt.DisableLoopStrengthReducePass = DisableLSR;<br>
+ Opt.DisableCodeGenPreparePass = DisableCGP;<br>
+ Opt.DisableMergeICmpsPass = DisableMergeICmps;<br>
+ Opt.DisablePartiallyInlineLibCallsPass = DisablePartialLibcallInlining;<br>
+ Opt.DisableConstantHoistingPass = DisableConstantHoisting;<br>
+ Opt.PrintAfterLSR = PrintLSR;<br>
+<br>
+ return Opt;<br>
+}<br>
+<br>
+static void registerPartialPipelineCallback(PassInstrumentationCallbacks &PIC,<br>
+ LLVMTargetMachine &LLVMTM) {<br>
+ StringRef StartBefore;<br>
+ StringRef StartAfter;<br>
+ StringRef StopBefore;<br>
+ StringRef StopAfter;<br>
+<br>
+ unsigned StartBeforeInstanceNum = 0;<br>
+ unsigned StartAfterInstanceNum = 0;<br>
+ unsigned StopBeforeInstanceNum = 0;<br>
+ unsigned StopAfterInstanceNum = 0;<br>
+<br>
+ std::tie(StartBefore, StartBeforeInstanceNum) =<br>
+ getPassNameAndInstanceNum(StartBeforeOpt);<br>
+ std::tie(StartAfter, StartAfterInstanceNum) =<br>
+ getPassNameAndInstanceNum(StartAfterOpt);<br>
+ std::tie(StopBefore, StopBeforeInstanceNum) =<br>
+ getPassNameAndInstanceNum(StopBeforeOpt);<br>
+ std::tie(StopAfter, StopAfterInstanceNum) =<br>
+ getPassNameAndInstanceNum(StopAfterOpt);<br>
+<br>
+ if (StartBefore.empty() && StartAfter.empty() && StopBefore.empty() &&<br>
+ StopAfter.empty())<br>
+ return;<br>
+<br>
+ std::tie(StartBefore, std::ignore) =<br>
+ LLVMTM.getPassNameFromLegacyName(StartBefore);<br>
+ std::tie(StartAfter, std::ignore) =<br>
+ LLVMTM.getPassNameFromLegacyName(StartAfter);<br>
+ std::tie(StopBefore, std::ignore) =<br>
+ LLVMTM.getPassNameFromLegacyName(StopBefore);<br>
+ std::tie(StopAfter, std::ignore) =<br>
+ LLVMTM.getPassNameFromLegacyName(StopAfter);<br>
+ if (!StartBefore.empty() && !StartAfter.empty())<br>
+ report_fatal_error(Twine(StartBeforeOptName) + Twine(" and ") +<br>
+ Twine(StartAfterOptName) + Twine(" specified!"));<br>
+ if (!StopBefore.empty() && !StopAfter.empty())<br>
+ report_fatal_error(Twine(StopBeforeOptName) + Twine(" and ") +<br>
+ Twine(StopAfterOptName) + Twine(" specified!"));<br>
+<br>
+ PIC.registerBeforePassCallback(<br>
+ [=, EnableCurrent = StartBefore.empty() && StartAfter.empty(),<br>
+ EnableNext = Optional<bool>(), StartBeforeCount = 0u,<br>
+ StartAfterCount = 0u, StopBeforeCount = 0u,<br>
+ StopAfterCount = 0u](StringRef P, Any) mutable {<br>
+ bool StartBeforePass = !StartBefore.empty() && P.contains(StartBefore);<br>
+ bool StartAfterPass = !StartAfter.empty() && P.contains(StartAfter);<br>
+ bool StopBeforePass = !StopBefore.empty() && P.contains(StopBefore);<br>
+ bool StopAfterPass = !StopAfter.empty() && P.contains(StopAfter);<br>
+<br>
+ // Implement -start-after/-stop-after<br>
+ if (EnableNext) {<br>
+ EnableCurrent = *EnableNext;<br>
+ EnableNext.reset();<br>
+ }<br>
+<br>
+ // Using PIC.registerAfterPassCallback won't work because if this<br>
+ // callback returns false, AfterPassCallback is also skipped.<br>
+ if (StartAfterPass && StartAfterCount++ == StartAfterInstanceNum) {<br>
+ assert(!EnableNext && "Error: assign to EnableNext more than once");<br>
+ EnableNext = true;<br>
+ }<br>
+ if (StopAfterPass && StopAfterCount++ == StopAfterInstanceNum) {<br>
+ assert(!EnableNext && "Error: assign to EnableNext more than once");<br>
+ EnableNext = false;<br>
+ }<br>
+<br>
+ if (StartBeforePass && StartBeforeCount++ == StartBeforeInstanceNum)<br>
+ EnableCurrent = true;<br>
+ if (StopBeforePass && StopBeforeCount++ == StopBeforeInstanceNum)<br>
+ EnableCurrent = false;<br>
+ return EnableCurrent;<br>
+ });<br>
+}<br>
+<br>
+void llvm::registerCodeGenCallback(PassInstrumentationCallbacks &PIC,<br>
+ LLVMTargetMachine &LLVMTM) {<br>
+<br>
+ // Register a callback for disabling passes.<br>
+ PIC.registerBeforePassCallback([](StringRef P, Any) {<br>
+<br>
+#define DISABLE_PASS(Option, Name) \<br>
+ if (Option && P.contains(#Name)) \<br>
+ return false;<br>
+ DISABLE_PASS(DisableBlockPlacement, MachineBlockPlacementPass)<br>
+ DISABLE_PASS(DisableBranchFold, BranchFolderPass)<br>
+ DISABLE_PASS(DisableCopyProp, MachineCopyPropagationPass)<br>
+ DISABLE_PASS(DisableEarlyIfConversion, EarlyIfConverterPass)<br>
+ DISABLE_PASS(DisableEarlyTailDup, EarlyTailDuplicatePass)<br>
+ DISABLE_PASS(DisableMachineCSE, MachineCSEPass)<br>
+ DISABLE_PASS(DisableMachineDCE, DeadMachineInstructionElimPass)<br>
+ DISABLE_PASS(DisableMachineLICM, EarlyMachineLICMPass)<br>
+ DISABLE_PASS(DisableMachineSink, MachineSinkingPass)<br>
+ DISABLE_PASS(DisablePostRAMachineLICM, MachineLICMPass)<br>
+ DISABLE_PASS(DisablePostRAMachineSink, PostRAMachineSinkingPass)<br>
+ DISABLE_PASS(DisablePostRASched, PostRASchedulerPass)<br>
+ DISABLE_PASS(DisableSSC, StackSlotColoringPass)<br>
+ DISABLE_PASS(DisableTailDuplicate, TailDuplicatePass)<br>
+<br>
+ return true;<br>
+ });<br>
+<br>
+ registerPartialPipelineCallback(PIC, LLVMTM);<br>
+}<br>
+<br>
// Out of line constructor provides default values for pass options and<br>
// registers all common codegen passes.<br>
TargetPassConfig::TargetPassConfig(LLVMTargetMachine &TM, PassManagerBase &pm)<br>
@@ -1012,10 +1152,11 @@ void TargetPassConfig::addMachinePasses() {<br>
addPass(&LiveDebugValuesID, false);<br>
<br>
if (TM->Options.EnableMachineOutliner && getOptLevel() != CodeGenOpt::None &&<br>
- EnableMachineOutliner != NeverOutline) {<br>
- bool RunOnAllFunctions = (EnableMachineOutliner == AlwaysOutline);<br>
- bool AddOutliner = RunOnAllFunctions ||<br>
- TM->Options.SupportsDefaultOutlining;<br>
+ EnableMachineOutliner != RunOutliner::NeverOutline) {<br>
+ bool RunOnAllFunctions =<br>
+ (EnableMachineOutliner == RunOutliner::AlwaysOutline);<br>
+ bool AddOutliner =<br>
+ RunOnAllFunctions || TM->Options.SupportsDefaultOutlining;<br>
if (AddOutliner)<br>
addPass(createMachineOutlinerPass(RunOnAllFunctions));<br>
}<br>
<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><mailto:<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a>><br>
<a href="https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits" rel="noreferrer" target="_blank">https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits</a><br>
</blockquote></div>