xref: /freebsd-src/contrib/llvm-project/llvm/lib/CodeGen/TargetPassConfig.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
10b57cec5SDimitry Andric //===- TargetPassConfig.cpp - Target independent code generation passes ---===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file defines interfaces to access the target independent code
100b57cec5SDimitry Andric // generation passes provided by the LLVM backend.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===---------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #include "llvm/CodeGen/TargetPassConfig.h"
150b57cec5SDimitry Andric #include "llvm/ADT/DenseMap.h"
160b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h"
170b57cec5SDimitry Andric #include "llvm/ADT/StringRef.h"
180b57cec5SDimitry Andric #include "llvm/Analysis/BasicAliasAnalysis.h"
190b57cec5SDimitry Andric #include "llvm/Analysis/CallGraphSCCPass.h"
200b57cec5SDimitry Andric #include "llvm/Analysis/ScopedNoAliasAA.h"
210b57cec5SDimitry Andric #include "llvm/Analysis/TargetTransformInfo.h"
220b57cec5SDimitry Andric #include "llvm/Analysis/TypeBasedAliasAnalysis.h"
2381ad6265SDimitry Andric #include "llvm/CodeGen/BasicBlockSectionsProfileReader.h"
240b57cec5SDimitry Andric #include "llvm/CodeGen/CSEConfigBase.h"
250b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h"
260b57cec5SDimitry Andric #include "llvm/CodeGen/MachinePassRegistry.h"
270b57cec5SDimitry Andric #include "llvm/CodeGen/Passes.h"
280b57cec5SDimitry Andric #include "llvm/CodeGen/RegAllocRegistry.h"
290b57cec5SDimitry Andric #include "llvm/IR/IRPrintingPasses.h"
300b57cec5SDimitry Andric #include "llvm/IR/LegacyPassManager.h"
31e8d8bef9SDimitry Andric #include "llvm/IR/PassInstrumentation.h"
320b57cec5SDimitry Andric #include "llvm/IR/Verifier.h"
33480093f4SDimitry Andric #include "llvm/InitializePasses.h"
340b57cec5SDimitry Andric #include "llvm/MC/MCAsmInfo.h"
350b57cec5SDimitry Andric #include "llvm/MC/MCTargetOptions.h"
360b57cec5SDimitry Andric #include "llvm/Pass.h"
370b57cec5SDimitry Andric #include "llvm/Support/CodeGen.h"
380b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h"
390b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
400b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
41fe6060f1SDimitry Andric #include "llvm/Support/Discriminator.h"
420b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
430b57cec5SDimitry Andric #include "llvm/Support/SaveAndRestore.h"
44480093f4SDimitry Andric #include "llvm/Support/Threading.h"
4506c3fb27SDimitry Andric #include "llvm/Support/VirtualFileSystem.h"
4606c3fb27SDimitry Andric #include "llvm/Support/WithColor.h"
47e8d8bef9SDimitry Andric #include "llvm/Target/CGPassBuilderOption.h"
480b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h"
490b57cec5SDimitry Andric #include "llvm/Transforms/Scalar.h"
500b57cec5SDimitry Andric #include "llvm/Transforms/Utils.h"
510b57cec5SDimitry Andric #include <cassert>
52bdd1243dSDimitry Andric #include <optional>
530b57cec5SDimitry Andric #include <string>
540b57cec5SDimitry Andric 
550b57cec5SDimitry Andric using namespace llvm;
560b57cec5SDimitry Andric 
578bcb0991SDimitry Andric static cl::opt<bool>
588bcb0991SDimitry Andric     EnableIPRA("enable-ipra", cl::init(false), cl::Hidden,
590b57cec5SDimitry Andric                cl::desc("Enable interprocedural register allocation "
600b57cec5SDimitry Andric                         "to reduce load/store at procedure calls."));
610b57cec5SDimitry Andric static cl::opt<bool> DisablePostRASched("disable-post-ra", cl::Hidden,
620b57cec5SDimitry Andric     cl::desc("Disable Post Regalloc Scheduler"));
630b57cec5SDimitry Andric static cl::opt<bool> DisableBranchFold("disable-branch-fold", cl::Hidden,
640b57cec5SDimitry Andric     cl::desc("Disable branch folding"));
650b57cec5SDimitry Andric static cl::opt<bool> DisableTailDuplicate("disable-tail-duplicate", cl::Hidden,
660b57cec5SDimitry Andric     cl::desc("Disable tail duplication"));
670b57cec5SDimitry Andric static cl::opt<bool> DisableEarlyTailDup("disable-early-taildup", cl::Hidden,
680b57cec5SDimitry Andric     cl::desc("Disable pre-register allocation tail duplication"));
690b57cec5SDimitry Andric static cl::opt<bool> DisableBlockPlacement("disable-block-placement",
700b57cec5SDimitry Andric     cl::Hidden, cl::desc("Disable probability-driven block placement"));
710b57cec5SDimitry Andric static cl::opt<bool> EnableBlockPlacementStats("enable-block-placement-stats",
720b57cec5SDimitry Andric     cl::Hidden, cl::desc("Collect probability-driven block placement stats"));
730b57cec5SDimitry Andric static cl::opt<bool> DisableSSC("disable-ssc", cl::Hidden,
740b57cec5SDimitry Andric     cl::desc("Disable Stack Slot Coloring"));
750b57cec5SDimitry Andric static cl::opt<bool> DisableMachineDCE("disable-machine-dce", cl::Hidden,
760b57cec5SDimitry Andric     cl::desc("Disable Machine Dead Code Elimination"));
770b57cec5SDimitry Andric static cl::opt<bool> DisableEarlyIfConversion("disable-early-ifcvt", cl::Hidden,
780b57cec5SDimitry Andric     cl::desc("Disable Early If-conversion"));
790b57cec5SDimitry Andric static cl::opt<bool> DisableMachineLICM("disable-machine-licm", cl::Hidden,
800b57cec5SDimitry Andric     cl::desc("Disable Machine LICM"));
810b57cec5SDimitry Andric static cl::opt<bool> DisableMachineCSE("disable-machine-cse", cl::Hidden,
820b57cec5SDimitry Andric     cl::desc("Disable Machine Common Subexpression Elimination"));
830b57cec5SDimitry Andric static cl::opt<cl::boolOrDefault> OptimizeRegAlloc(
840b57cec5SDimitry Andric     "optimize-regalloc", cl::Hidden,
850b57cec5SDimitry Andric     cl::desc("Enable optimized register allocation compilation path."));
860b57cec5SDimitry Andric static cl::opt<bool> DisablePostRAMachineLICM("disable-postra-machine-licm",
870b57cec5SDimitry Andric     cl::Hidden,
880b57cec5SDimitry Andric     cl::desc("Disable Machine LICM"));
890b57cec5SDimitry Andric static cl::opt<bool> DisableMachineSink("disable-machine-sink", cl::Hidden,
900b57cec5SDimitry Andric     cl::desc("Disable Machine Sinking"));
910b57cec5SDimitry Andric static cl::opt<bool> DisablePostRAMachineSink("disable-postra-machine-sink",
920b57cec5SDimitry Andric     cl::Hidden,
930b57cec5SDimitry Andric     cl::desc("Disable PostRA Machine Sinking"));
940b57cec5SDimitry Andric static cl::opt<bool> DisableLSR("disable-lsr", cl::Hidden,
950b57cec5SDimitry Andric     cl::desc("Disable Loop Strength Reduction Pass"));
960b57cec5SDimitry Andric static cl::opt<bool> DisableConstantHoisting("disable-constant-hoisting",
970b57cec5SDimitry Andric     cl::Hidden, cl::desc("Disable ConstantHoisting"));
980b57cec5SDimitry Andric static cl::opt<bool> DisableCGP("disable-cgp", cl::Hidden,
990b57cec5SDimitry Andric     cl::desc("Disable Codegen Prepare"));
1000b57cec5SDimitry Andric static cl::opt<bool> DisableCopyProp("disable-copyprop", cl::Hidden,
1010b57cec5SDimitry Andric     cl::desc("Disable Copy Propagation pass"));
1020b57cec5SDimitry Andric static cl::opt<bool> DisablePartialLibcallInlining("disable-partial-libcall-inlining",
1030b57cec5SDimitry Andric     cl::Hidden, cl::desc("Disable Partial Libcall Inlining"));
10406c3fb27SDimitry Andric static cl::opt<bool> DisableAtExitBasedGlobalDtorLowering(
10506c3fb27SDimitry Andric     "disable-atexit-based-global-dtor-lowering", cl::Hidden,
10606c3fb27SDimitry Andric     cl::desc("For MachO, disable atexit()-based global destructor lowering"));
1070b57cec5SDimitry Andric static cl::opt<bool> EnableImplicitNullChecks(
1080b57cec5SDimitry Andric     "enable-implicit-null-checks",
1090b57cec5SDimitry Andric     cl::desc("Fold null checks into faulting memory operations"),
1100b57cec5SDimitry Andric     cl::init(false), cl::Hidden);
1110b57cec5SDimitry Andric static cl::opt<bool> DisableMergeICmps("disable-mergeicmps",
1120b57cec5SDimitry Andric     cl::desc("Disable MergeICmps Pass"),
1130b57cec5SDimitry Andric     cl::init(false), cl::Hidden);
1140b57cec5SDimitry Andric static cl::opt<bool> PrintLSR("print-lsr-output", cl::Hidden,
1150b57cec5SDimitry Andric     cl::desc("Print LLVM IR produced by the loop-reduce pass"));
1165f757f3fSDimitry Andric static cl::opt<bool>
1175f757f3fSDimitry Andric     PrintISelInput("print-isel-input", cl::Hidden,
1180b57cec5SDimitry Andric                    cl::desc("Print LLVM IR input to isel pass"));
1190b57cec5SDimitry Andric static cl::opt<cl::boolOrDefault>
1200b57cec5SDimitry Andric     VerifyMachineCode("verify-machineinstrs", cl::Hidden,
12181ad6265SDimitry Andric                       cl::desc("Verify generated machine code"));
12281ad6265SDimitry Andric static cl::opt<cl::boolOrDefault>
12381ad6265SDimitry Andric     DebugifyAndStripAll("debugify-and-strip-all-safe", cl::Hidden,
12481ad6265SDimitry Andric                         cl::desc("Debugify MIR before and Strip debug after "
12581ad6265SDimitry Andric                                  "each pass except those known to be unsafe "
12681ad6265SDimitry Andric                                  "when debug info is present"));
127e8d8bef9SDimitry Andric static cl::opt<cl::boolOrDefault> DebugifyCheckAndStripAll(
128e8d8bef9SDimitry Andric     "debugify-check-and-strip-all-safe", cl::Hidden,
129e8d8bef9SDimitry Andric     cl::desc(
130e8d8bef9SDimitry Andric         "Debugify MIR before, by checking and stripping the debug info after, "
13181ad6265SDimitry Andric         "each pass except those known to be unsafe when debug info is "
13281ad6265SDimitry Andric         "present"));
1330b57cec5SDimitry Andric // Enable or disable the MachineOutliner.
1340b57cec5SDimitry Andric static cl::opt<RunOutliner> EnableMachineOutliner(
1350b57cec5SDimitry Andric     "enable-machine-outliner", cl::desc("Enable the machine outliner"),
136e8d8bef9SDimitry Andric     cl::Hidden, cl::ValueOptional, cl::init(RunOutliner::TargetDefault),
137e8d8bef9SDimitry Andric     cl::values(clEnumValN(RunOutliner::AlwaysOutline, "always",
1380b57cec5SDimitry Andric                           "Run on all functions guaranteed to be beneficial"),
139e8d8bef9SDimitry Andric                clEnumValN(RunOutliner::NeverOutline, "never",
140e8d8bef9SDimitry Andric                           "Disable all outlining"),
1410b57cec5SDimitry Andric                // Sentinel value for unspecified option.
142e8d8bef9SDimitry Andric                clEnumValN(RunOutliner::AlwaysOutline, "", "")));
14381ad6265SDimitry Andric // Disable the pass to fix unwind information. Whether the pass is included in
14481ad6265SDimitry Andric // the pipeline is controlled via the target options, this option serves as
14581ad6265SDimitry Andric // manual override.
14681ad6265SDimitry Andric static cl::opt<bool> DisableCFIFixup("disable-cfi-fixup", cl::Hidden,
14781ad6265SDimitry Andric                                      cl::desc("Disable the CFI fixup pass"));
1480b57cec5SDimitry Andric // Enable or disable FastISel. Both options are needed, because
1490b57cec5SDimitry Andric // FastISel is enabled by default with -fast, and we wish to be
1500b57cec5SDimitry Andric // able to enable or disable fast-isel independently from -O0.
1510b57cec5SDimitry Andric static cl::opt<cl::boolOrDefault>
1520b57cec5SDimitry Andric EnableFastISelOption("fast-isel", cl::Hidden,
1530b57cec5SDimitry Andric   cl::desc("Enable the \"fast\" instruction selector"));
1540b57cec5SDimitry Andric 
1550b57cec5SDimitry Andric static cl::opt<cl::boolOrDefault> EnableGlobalISelOption(
1560b57cec5SDimitry Andric     "global-isel", cl::Hidden,
1570b57cec5SDimitry Andric     cl::desc("Enable the \"global\" instruction selector"));
1580b57cec5SDimitry Andric 
159e8d8bef9SDimitry Andric // FIXME: remove this after switching to NPM or GlobalISel, whichever gets there
160e8d8bef9SDimitry Andric //        first...
161e8d8bef9SDimitry Andric static cl::opt<bool>
162e8d8bef9SDimitry Andric     PrintAfterISel("print-after-isel", cl::init(false), cl::Hidden,
163e8d8bef9SDimitry Andric                    cl::desc("Print machine instrs after ISel"));
1640b57cec5SDimitry Andric 
1650b57cec5SDimitry Andric static cl::opt<GlobalISelAbortMode> EnableGlobalISelAbort(
1660b57cec5SDimitry Andric     "global-isel-abort", cl::Hidden,
1670b57cec5SDimitry Andric     cl::desc("Enable abort calls when \"global\" instruction selection "
1680b57cec5SDimitry Andric              "fails to lower/select an instruction"),
1690b57cec5SDimitry Andric     cl::values(
1700b57cec5SDimitry Andric         clEnumValN(GlobalISelAbortMode::Disable, "0", "Disable the abort"),
1710b57cec5SDimitry Andric         clEnumValN(GlobalISelAbortMode::Enable, "1", "Enable the abort"),
1720b57cec5SDimitry Andric         clEnumValN(GlobalISelAbortMode::DisableWithDiag, "2",
1730b57cec5SDimitry Andric                    "Disable the abort but emit a diagnostic on failure")));
1740b57cec5SDimitry Andric 
175349cc55cSDimitry Andric // Disable MIRProfileLoader before RegAlloc. This is for for debugging and
176349cc55cSDimitry Andric // tuning purpose.
177349cc55cSDimitry Andric static cl::opt<bool> DisableRAFSProfileLoader(
17881ad6265SDimitry Andric     "disable-ra-fsprofile-loader", cl::init(false), cl::Hidden,
179349cc55cSDimitry Andric     cl::desc("Disable MIRProfileLoader before RegAlloc"));
180349cc55cSDimitry Andric // Disable MIRProfileLoader before BloackPlacement. This is for for debugging
181349cc55cSDimitry Andric // and tuning purpose.
182349cc55cSDimitry Andric static cl::opt<bool> DisableLayoutFSProfileLoader(
18381ad6265SDimitry Andric     "disable-layout-fsprofile-loader", cl::init(false), cl::Hidden,
184349cc55cSDimitry Andric     cl::desc("Disable MIRProfileLoader before BlockPlacement"));
185349cc55cSDimitry Andric // Specify FSProfile file name.
186349cc55cSDimitry Andric static cl::opt<std::string>
187349cc55cSDimitry Andric     FSProfileFile("fs-profile-file", cl::init(""), cl::value_desc("filename"),
188349cc55cSDimitry Andric                   cl::desc("Flow Sensitive profile file name."), cl::Hidden);
189349cc55cSDimitry Andric // Specify Remapping file for FSProfile.
190349cc55cSDimitry Andric static cl::opt<std::string> FSRemappingFile(
191349cc55cSDimitry Andric     "fs-remapping-file", cl::init(""), cl::value_desc("filename"),
192349cc55cSDimitry Andric     cl::desc("Flow Sensitive profile remapping file name."), cl::Hidden);
193fe6060f1SDimitry Andric 
1940b57cec5SDimitry Andric // Temporary option to allow experimenting with MachineScheduler as a post-RA
1950b57cec5SDimitry Andric // scheduler. Targets can "properly" enable this with
1960b57cec5SDimitry Andric // substitutePass(&PostRASchedulerID, &PostMachineSchedulerID).
1970b57cec5SDimitry Andric // Targets can return true in targetSchedulesPostRAScheduling() and
1980b57cec5SDimitry Andric // insert a PostRA scheduling pass wherever it wants.
1998bcb0991SDimitry Andric static cl::opt<bool> MISchedPostRA(
2008bcb0991SDimitry Andric     "misched-postra", cl::Hidden,
2018bcb0991SDimitry Andric     cl::desc(
2028bcb0991SDimitry Andric         "Run MachineScheduler post regalloc (independent of preRA sched)"));
2030b57cec5SDimitry Andric 
2040b57cec5SDimitry Andric // Experimental option to run live interval analysis early.
2050b57cec5SDimitry Andric static cl::opt<bool> EarlyLiveIntervals("early-live-intervals", cl::Hidden,
2060b57cec5SDimitry Andric     cl::desc("Run live interval analysis earlier in the pipeline"));
2070b57cec5SDimitry Andric 
208*0fca6ea1SDimitry Andric static cl::opt<bool> DisableReplaceWithVecLib(
209*0fca6ea1SDimitry Andric     "disable-replace-with-vec-lib", cl::Hidden,
210*0fca6ea1SDimitry Andric     cl::desc("Disable replace with vector math call pass"));
211*0fca6ea1SDimitry Andric 
2120b57cec5SDimitry Andric /// Option names for limiting the codegen pipeline.
2130b57cec5SDimitry Andric /// Those are used in error reporting and we didn't want
2140b57cec5SDimitry Andric /// to duplicate their names all over the place.
215480093f4SDimitry Andric static const char StartAfterOptName[] = "start-after";
216480093f4SDimitry Andric static const char StartBeforeOptName[] = "start-before";
217480093f4SDimitry Andric static const char StopAfterOptName[] = "stop-after";
218480093f4SDimitry Andric static const char StopBeforeOptName[] = "stop-before";
2190b57cec5SDimitry Andric 
2200b57cec5SDimitry Andric static cl::opt<std::string>
2210b57cec5SDimitry Andric     StartAfterOpt(StringRef(StartAfterOptName),
2220b57cec5SDimitry Andric                   cl::desc("Resume compilation after a specific pass"),
2230b57cec5SDimitry Andric                   cl::value_desc("pass-name"), cl::init(""), cl::Hidden);
2240b57cec5SDimitry Andric 
2250b57cec5SDimitry Andric static cl::opt<std::string>
2260b57cec5SDimitry Andric     StartBeforeOpt(StringRef(StartBeforeOptName),
2270b57cec5SDimitry Andric                    cl::desc("Resume compilation before a specific pass"),
2280b57cec5SDimitry Andric                    cl::value_desc("pass-name"), cl::init(""), cl::Hidden);
2290b57cec5SDimitry Andric 
2300b57cec5SDimitry Andric static cl::opt<std::string>
2310b57cec5SDimitry Andric     StopAfterOpt(StringRef(StopAfterOptName),
2320b57cec5SDimitry Andric                  cl::desc("Stop compilation after a specific pass"),
2330b57cec5SDimitry Andric                  cl::value_desc("pass-name"), cl::init(""), cl::Hidden);
2340b57cec5SDimitry Andric 
2350b57cec5SDimitry Andric static cl::opt<std::string>
2360b57cec5SDimitry Andric     StopBeforeOpt(StringRef(StopBeforeOptName),
2370b57cec5SDimitry Andric                   cl::desc("Stop compilation before a specific pass"),
2380b57cec5SDimitry Andric                   cl::value_desc("pass-name"), cl::init(""), cl::Hidden);
2390b57cec5SDimitry Andric 
240e8d8bef9SDimitry Andric /// Enable the machine function splitter pass.
241e8d8bef9SDimitry Andric static cl::opt<bool> EnableMachineFunctionSplitter(
242e8d8bef9SDimitry Andric     "enable-split-machine-functions", cl::Hidden,
243e8d8bef9SDimitry Andric     cl::desc("Split out cold blocks from machine functions based on profile "
244e8d8bef9SDimitry Andric              "information."));
245e8d8bef9SDimitry Andric 
246e8d8bef9SDimitry Andric /// Disable the expand reductions pass for testing.
247e8d8bef9SDimitry Andric static cl::opt<bool> DisableExpandReductions(
248e8d8bef9SDimitry Andric     "disable-expand-reductions", cl::init(false), cl::Hidden,
249e8d8bef9SDimitry Andric     cl::desc("Disable the expand reduction intrinsics pass from running"));
250e8d8bef9SDimitry Andric 
25181ad6265SDimitry Andric /// Disable the select optimization pass.
25281ad6265SDimitry Andric static cl::opt<bool> DisableSelectOptimize(
25381ad6265SDimitry Andric     "disable-select-optimize", cl::init(true), cl::Hidden,
25481ad6265SDimitry Andric     cl::desc("Disable the select-optimization pass from running"));
25581ad6265SDimitry Andric 
2565f757f3fSDimitry Andric /// Enable garbage-collecting empty basic blocks.
2575f757f3fSDimitry Andric static cl::opt<bool>
2585f757f3fSDimitry Andric     GCEmptyBlocks("gc-empty-basic-blocks", cl::init(false), cl::Hidden,
2595f757f3fSDimitry Andric                   cl::desc("Enable garbage-collecting empty basic blocks"));
2605f757f3fSDimitry Andric 
2610b57cec5SDimitry Andric /// Allow standard passes to be disabled by command line options. This supports
2620b57cec5SDimitry Andric /// simple binary flags that either suppress the pass or do nothing.
2630b57cec5SDimitry Andric /// i.e. -disable-mypass=false has no effect.
2640b57cec5SDimitry Andric /// These should be converted to boolOrDefault in order to use applyOverride.
2650b57cec5SDimitry Andric static IdentifyingPassPtr applyDisable(IdentifyingPassPtr PassID,
2660b57cec5SDimitry Andric                                        bool Override) {
2670b57cec5SDimitry Andric   if (Override)
2680b57cec5SDimitry Andric     return IdentifyingPassPtr();
2690b57cec5SDimitry Andric   return PassID;
2700b57cec5SDimitry Andric }
2710b57cec5SDimitry Andric 
2720b57cec5SDimitry Andric /// Allow standard passes to be disabled by the command line, regardless of who
2730b57cec5SDimitry Andric /// is adding the pass.
2740b57cec5SDimitry Andric ///
2750b57cec5SDimitry Andric /// StandardID is the pass identified in the standard pass pipeline and provided
2760b57cec5SDimitry Andric /// to addPass(). It may be a target-specific ID in the case that the target
2770b57cec5SDimitry Andric /// directly adds its own pass, but in that case we harmlessly fall through.
2780b57cec5SDimitry Andric ///
2790b57cec5SDimitry Andric /// TargetID is the pass that the target has configured to override StandardID.
2800b57cec5SDimitry Andric ///
2810b57cec5SDimitry Andric /// StandardID may be a pseudo ID. In that case TargetID is the name of the real
2820b57cec5SDimitry Andric /// pass to run. This allows multiple options to control a single pass depending
2830b57cec5SDimitry Andric /// on where in the pipeline that pass is added.
2840b57cec5SDimitry Andric static IdentifyingPassPtr overridePass(AnalysisID StandardID,
2850b57cec5SDimitry Andric                                        IdentifyingPassPtr TargetID) {
2860b57cec5SDimitry Andric   if (StandardID == &PostRASchedulerID)
2870b57cec5SDimitry Andric     return applyDisable(TargetID, DisablePostRASched);
2880b57cec5SDimitry Andric 
2890b57cec5SDimitry Andric   if (StandardID == &BranchFolderPassID)
2900b57cec5SDimitry Andric     return applyDisable(TargetID, DisableBranchFold);
2910b57cec5SDimitry Andric 
2920b57cec5SDimitry Andric   if (StandardID == &TailDuplicateID)
2930b57cec5SDimitry Andric     return applyDisable(TargetID, DisableTailDuplicate);
2940b57cec5SDimitry Andric 
2950b57cec5SDimitry Andric   if (StandardID == &EarlyTailDuplicateID)
2960b57cec5SDimitry Andric     return applyDisable(TargetID, DisableEarlyTailDup);
2970b57cec5SDimitry Andric 
2980b57cec5SDimitry Andric   if (StandardID == &MachineBlockPlacementID)
2990b57cec5SDimitry Andric     return applyDisable(TargetID, DisableBlockPlacement);
3000b57cec5SDimitry Andric 
3010b57cec5SDimitry Andric   if (StandardID == &StackSlotColoringID)
3020b57cec5SDimitry Andric     return applyDisable(TargetID, DisableSSC);
3030b57cec5SDimitry Andric 
3040b57cec5SDimitry Andric   if (StandardID == &DeadMachineInstructionElimID)
3050b57cec5SDimitry Andric     return applyDisable(TargetID, DisableMachineDCE);
3060b57cec5SDimitry Andric 
3070b57cec5SDimitry Andric   if (StandardID == &EarlyIfConverterID)
3080b57cec5SDimitry Andric     return applyDisable(TargetID, DisableEarlyIfConversion);
3090b57cec5SDimitry Andric 
3100b57cec5SDimitry Andric   if (StandardID == &EarlyMachineLICMID)
3110b57cec5SDimitry Andric     return applyDisable(TargetID, DisableMachineLICM);
3120b57cec5SDimitry Andric 
3130b57cec5SDimitry Andric   if (StandardID == &MachineCSEID)
3140b57cec5SDimitry Andric     return applyDisable(TargetID, DisableMachineCSE);
3150b57cec5SDimitry Andric 
3160b57cec5SDimitry Andric   if (StandardID == &MachineLICMID)
3170b57cec5SDimitry Andric     return applyDisable(TargetID, DisablePostRAMachineLICM);
3180b57cec5SDimitry Andric 
3190b57cec5SDimitry Andric   if (StandardID == &MachineSinkingID)
3200b57cec5SDimitry Andric     return applyDisable(TargetID, DisableMachineSink);
3210b57cec5SDimitry Andric 
3220b57cec5SDimitry Andric   if (StandardID == &PostRAMachineSinkingID)
3230b57cec5SDimitry Andric     return applyDisable(TargetID, DisablePostRAMachineSink);
3240b57cec5SDimitry Andric 
3250b57cec5SDimitry Andric   if (StandardID == &MachineCopyPropagationID)
3260b57cec5SDimitry Andric     return applyDisable(TargetID, DisableCopyProp);
3270b57cec5SDimitry Andric 
3280b57cec5SDimitry Andric   return TargetID;
3290b57cec5SDimitry Andric }
3300b57cec5SDimitry Andric 
331349cc55cSDimitry Andric // Find the FSProfile file name. The internal option takes the precedence
332349cc55cSDimitry Andric // before getting from TargetMachine.
33304eeddc0SDimitry Andric static std::string getFSProfileFile(const TargetMachine *TM) {
334349cc55cSDimitry Andric   if (!FSProfileFile.empty())
335349cc55cSDimitry Andric     return FSProfileFile.getValue();
336bdd1243dSDimitry Andric   const std::optional<PGOOptions> &PGOOpt = TM->getPGOOption();
337bdd1243dSDimitry Andric   if (PGOOpt == std::nullopt || PGOOpt->Action != PGOOptions::SampleUse)
338349cc55cSDimitry Andric     return std::string();
339349cc55cSDimitry Andric   return PGOOpt->ProfileFile;
340349cc55cSDimitry Andric }
341349cc55cSDimitry Andric 
342349cc55cSDimitry Andric // Find the Profile remapping file name. The internal option takes the
343349cc55cSDimitry Andric // precedence before getting from TargetMachine.
34404eeddc0SDimitry Andric static std::string getFSRemappingFile(const TargetMachine *TM) {
345349cc55cSDimitry Andric   if (!FSRemappingFile.empty())
346349cc55cSDimitry Andric     return FSRemappingFile.getValue();
347bdd1243dSDimitry Andric   const std::optional<PGOOptions> &PGOOpt = TM->getPGOOption();
348bdd1243dSDimitry Andric   if (PGOOpt == std::nullopt || PGOOpt->Action != PGOOptions::SampleUse)
349349cc55cSDimitry Andric     return std::string();
350349cc55cSDimitry Andric   return PGOOpt->ProfileRemappingFile;
351349cc55cSDimitry Andric }
352349cc55cSDimitry Andric 
3530b57cec5SDimitry Andric //===---------------------------------------------------------------------===//
3540b57cec5SDimitry Andric /// TargetPassConfig
3550b57cec5SDimitry Andric //===---------------------------------------------------------------------===//
3560b57cec5SDimitry Andric 
3570b57cec5SDimitry Andric INITIALIZE_PASS(TargetPassConfig, "targetpassconfig",
3580b57cec5SDimitry Andric                 "Target Pass Configuration", false, false)
3590b57cec5SDimitry Andric char TargetPassConfig::ID = 0;
3600b57cec5SDimitry Andric 
3610b57cec5SDimitry Andric namespace {
3620b57cec5SDimitry Andric 
3630b57cec5SDimitry Andric struct InsertedPass {
3640b57cec5SDimitry Andric   AnalysisID TargetPassID;
3650b57cec5SDimitry Andric   IdentifyingPassPtr InsertedPassID;
3660b57cec5SDimitry Andric 
367349cc55cSDimitry Andric   InsertedPass(AnalysisID TargetPassID, IdentifyingPassPtr InsertedPassID)
368349cc55cSDimitry Andric       : TargetPassID(TargetPassID), InsertedPassID(InsertedPassID) {}
3690b57cec5SDimitry Andric 
3700b57cec5SDimitry Andric   Pass *getInsertedPass() const {
3710b57cec5SDimitry Andric     assert(InsertedPassID.isValid() && "Illegal Pass ID!");
3720b57cec5SDimitry Andric     if (InsertedPassID.isInstance())
3730b57cec5SDimitry Andric       return InsertedPassID.getInstance();
3740b57cec5SDimitry Andric     Pass *NP = Pass::createPass(InsertedPassID.getID());
3750b57cec5SDimitry Andric     assert(NP && "Pass ID not registered");
3760b57cec5SDimitry Andric     return NP;
3770b57cec5SDimitry Andric   }
3780b57cec5SDimitry Andric };
3790b57cec5SDimitry Andric 
3800b57cec5SDimitry Andric } // end anonymous namespace
3810b57cec5SDimitry Andric 
3820b57cec5SDimitry Andric namespace llvm {
3830b57cec5SDimitry Andric 
384fe6060f1SDimitry Andric extern cl::opt<bool> EnableFSDiscriminator;
385fe6060f1SDimitry Andric 
3860b57cec5SDimitry Andric class PassConfigImpl {
3870b57cec5SDimitry Andric public:
3880b57cec5SDimitry Andric   // List of passes explicitly substituted by this target. Normally this is
3890b57cec5SDimitry Andric   // empty, but it is a convenient way to suppress or replace specific passes
3900b57cec5SDimitry Andric   // that are part of a standard pass pipeline without overridding the entire
3910b57cec5SDimitry Andric   // pipeline. This mechanism allows target options to inherit a standard pass's
3920b57cec5SDimitry Andric   // user interface. For example, a target may disable a standard pass by
3930b57cec5SDimitry Andric   // default by substituting a pass ID of zero, and the user may still enable
3940b57cec5SDimitry Andric   // that standard pass with an explicit command line option.
3950b57cec5SDimitry Andric   DenseMap<AnalysisID,IdentifyingPassPtr> TargetPasses;
3960b57cec5SDimitry Andric 
3970b57cec5SDimitry Andric   /// Store the pairs of <AnalysisID, AnalysisID> of which the second pass
3980b57cec5SDimitry Andric   /// is inserted after each instance of the first one.
3990b57cec5SDimitry Andric   SmallVector<InsertedPass, 4> InsertedPasses;
4000b57cec5SDimitry Andric };
4010b57cec5SDimitry Andric 
4020b57cec5SDimitry Andric } // end namespace llvm
4030b57cec5SDimitry Andric 
4040b57cec5SDimitry Andric // Out of line virtual method.
4050b57cec5SDimitry Andric TargetPassConfig::~TargetPassConfig() {
4060b57cec5SDimitry Andric   delete Impl;
4070b57cec5SDimitry Andric }
4080b57cec5SDimitry Andric 
4090b57cec5SDimitry Andric static const PassInfo *getPassInfo(StringRef PassName) {
4100b57cec5SDimitry Andric   if (PassName.empty())
4110b57cec5SDimitry Andric     return nullptr;
4120b57cec5SDimitry Andric 
4130b57cec5SDimitry Andric   const PassRegistry &PR = *PassRegistry::getPassRegistry();
4140b57cec5SDimitry Andric   const PassInfo *PI = PR.getPassInfo(PassName);
4150b57cec5SDimitry Andric   if (!PI)
4160b57cec5SDimitry Andric     report_fatal_error(Twine('\"') + Twine(PassName) +
4170b57cec5SDimitry Andric                        Twine("\" pass is not registered."));
4180b57cec5SDimitry Andric   return PI;
4190b57cec5SDimitry Andric }
4200b57cec5SDimitry Andric 
4210b57cec5SDimitry Andric static AnalysisID getPassIDFromName(StringRef PassName) {
4220b57cec5SDimitry Andric   const PassInfo *PI = getPassInfo(PassName);
4230b57cec5SDimitry Andric   return PI ? PI->getTypeInfo() : nullptr;
4240b57cec5SDimitry Andric }
4250b57cec5SDimitry Andric 
4260b57cec5SDimitry Andric static std::pair<StringRef, unsigned>
4270b57cec5SDimitry Andric getPassNameAndInstanceNum(StringRef PassName) {
4280b57cec5SDimitry Andric   StringRef Name, InstanceNumStr;
4290b57cec5SDimitry Andric   std::tie(Name, InstanceNumStr) = PassName.split(',');
4300b57cec5SDimitry Andric 
4310b57cec5SDimitry Andric   unsigned InstanceNum = 0;
4320b57cec5SDimitry Andric   if (!InstanceNumStr.empty() && InstanceNumStr.getAsInteger(10, InstanceNum))
4330b57cec5SDimitry Andric     report_fatal_error("invalid pass instance specifier " + PassName);
4340b57cec5SDimitry Andric 
4350b57cec5SDimitry Andric   return std::make_pair(Name, InstanceNum);
4360b57cec5SDimitry Andric }
4370b57cec5SDimitry Andric 
4380b57cec5SDimitry Andric void TargetPassConfig::setStartStopPasses() {
4390b57cec5SDimitry Andric   StringRef StartBeforeName;
4400b57cec5SDimitry Andric   std::tie(StartBeforeName, StartBeforeInstanceNum) =
4410b57cec5SDimitry Andric     getPassNameAndInstanceNum(StartBeforeOpt);
4420b57cec5SDimitry Andric 
4430b57cec5SDimitry Andric   StringRef StartAfterName;
4440b57cec5SDimitry Andric   std::tie(StartAfterName, StartAfterInstanceNum) =
4450b57cec5SDimitry Andric     getPassNameAndInstanceNum(StartAfterOpt);
4460b57cec5SDimitry Andric 
4470b57cec5SDimitry Andric   StringRef StopBeforeName;
4480b57cec5SDimitry Andric   std::tie(StopBeforeName, StopBeforeInstanceNum)
4490b57cec5SDimitry Andric     = getPassNameAndInstanceNum(StopBeforeOpt);
4500b57cec5SDimitry Andric 
4510b57cec5SDimitry Andric   StringRef StopAfterName;
4520b57cec5SDimitry Andric   std::tie(StopAfterName, StopAfterInstanceNum)
4530b57cec5SDimitry Andric     = getPassNameAndInstanceNum(StopAfterOpt);
4540b57cec5SDimitry Andric 
4550b57cec5SDimitry Andric   StartBefore = getPassIDFromName(StartBeforeName);
4560b57cec5SDimitry Andric   StartAfter = getPassIDFromName(StartAfterName);
4570b57cec5SDimitry Andric   StopBefore = getPassIDFromName(StopBeforeName);
4580b57cec5SDimitry Andric   StopAfter = getPassIDFromName(StopAfterName);
4590b57cec5SDimitry Andric   if (StartBefore && StartAfter)
4600b57cec5SDimitry Andric     report_fatal_error(Twine(StartBeforeOptName) + Twine(" and ") +
4610b57cec5SDimitry Andric                        Twine(StartAfterOptName) + Twine(" specified!"));
4620b57cec5SDimitry Andric   if (StopBefore && StopAfter)
4630b57cec5SDimitry Andric     report_fatal_error(Twine(StopBeforeOptName) + Twine(" and ") +
4640b57cec5SDimitry Andric                        Twine(StopAfterOptName) + Twine(" specified!"));
4650b57cec5SDimitry Andric   Started = (StartAfter == nullptr) && (StartBefore == nullptr);
4660b57cec5SDimitry Andric }
4670b57cec5SDimitry Andric 
468e8d8bef9SDimitry Andric CGPassBuilderOption llvm::getCGPassBuilderOption() {
469e8d8bef9SDimitry Andric   CGPassBuilderOption Opt;
470e8d8bef9SDimitry Andric 
471e8d8bef9SDimitry Andric #define SET_OPTION(Option)                                                     \
472e8d8bef9SDimitry Andric   if (Option.getNumOccurrences())                                              \
473e8d8bef9SDimitry Andric     Opt.Option = Option;
474e8d8bef9SDimitry Andric 
475e8d8bef9SDimitry Andric   SET_OPTION(EnableFastISelOption)
476e8d8bef9SDimitry Andric   SET_OPTION(EnableGlobalISelAbort)
477e8d8bef9SDimitry Andric   SET_OPTION(EnableGlobalISelOption)
478e8d8bef9SDimitry Andric   SET_OPTION(EnableIPRA)
479e8d8bef9SDimitry Andric   SET_OPTION(OptimizeRegAlloc)
480e8d8bef9SDimitry Andric   SET_OPTION(VerifyMachineCode)
4815f757f3fSDimitry Andric   SET_OPTION(DisableAtExitBasedGlobalDtorLowering)
4825f757f3fSDimitry Andric   SET_OPTION(DisableExpandReductions)
4835f757f3fSDimitry Andric   SET_OPTION(PrintAfterISel)
4845f757f3fSDimitry Andric   SET_OPTION(FSProfileFile)
4855f757f3fSDimitry Andric   SET_OPTION(GCEmptyBlocks)
486e8d8bef9SDimitry Andric 
487e8d8bef9SDimitry Andric #define SET_BOOLEAN_OPTION(Option) Opt.Option = Option;
488e8d8bef9SDimitry Andric 
489e8d8bef9SDimitry Andric   SET_BOOLEAN_OPTION(EarlyLiveIntervals)
490e8d8bef9SDimitry Andric   SET_BOOLEAN_OPTION(EnableBlockPlacementStats)
491e8d8bef9SDimitry Andric   SET_BOOLEAN_OPTION(EnableImplicitNullChecks)
492e8d8bef9SDimitry Andric   SET_BOOLEAN_OPTION(EnableMachineOutliner)
493e8d8bef9SDimitry Andric   SET_BOOLEAN_OPTION(MISchedPostRA)
494e8d8bef9SDimitry Andric   SET_BOOLEAN_OPTION(DisableMergeICmps)
495e8d8bef9SDimitry Andric   SET_BOOLEAN_OPTION(DisableLSR)
496e8d8bef9SDimitry Andric   SET_BOOLEAN_OPTION(DisableConstantHoisting)
497e8d8bef9SDimitry Andric   SET_BOOLEAN_OPTION(DisableCGP)
498e8d8bef9SDimitry Andric   SET_BOOLEAN_OPTION(DisablePartialLibcallInlining)
49981ad6265SDimitry Andric   SET_BOOLEAN_OPTION(DisableSelectOptimize)
500e8d8bef9SDimitry Andric   SET_BOOLEAN_OPTION(PrintLSR)
501e8d8bef9SDimitry Andric   SET_BOOLEAN_OPTION(PrintISelInput)
5025f757f3fSDimitry Andric   SET_BOOLEAN_OPTION(DebugifyAndStripAll)
5035f757f3fSDimitry Andric   SET_BOOLEAN_OPTION(DebugifyCheckAndStripAll)
5045f757f3fSDimitry Andric   SET_BOOLEAN_OPTION(DisableRAFSProfileLoader)
5055f757f3fSDimitry Andric   SET_BOOLEAN_OPTION(DisableCFIFixup)
5065f757f3fSDimitry Andric   SET_BOOLEAN_OPTION(EnableMachineFunctionSplitter)
507e8d8bef9SDimitry Andric 
508e8d8bef9SDimitry Andric   return Opt;
509e8d8bef9SDimitry Andric }
510e8d8bef9SDimitry Andric 
511e8d8bef9SDimitry Andric void llvm::registerCodeGenCallback(PassInstrumentationCallbacks &PIC,
512e8d8bef9SDimitry Andric                                    LLVMTargetMachine &LLVMTM) {
513e8d8bef9SDimitry Andric 
514e8d8bef9SDimitry Andric   // Register a callback for disabling passes.
515e8d8bef9SDimitry Andric   PIC.registerShouldRunOptionalPassCallback([](StringRef P, Any) {
516e8d8bef9SDimitry Andric 
517e8d8bef9SDimitry Andric #define DISABLE_PASS(Option, Name)                                             \
518e8d8bef9SDimitry Andric   if (Option && P.contains(#Name))                                             \
519e8d8bef9SDimitry Andric     return false;
520e8d8bef9SDimitry Andric     DISABLE_PASS(DisableBlockPlacement, MachineBlockPlacementPass)
521e8d8bef9SDimitry Andric     DISABLE_PASS(DisableBranchFold, BranchFolderPass)
522e8d8bef9SDimitry Andric     DISABLE_PASS(DisableCopyProp, MachineCopyPropagationPass)
523e8d8bef9SDimitry Andric     DISABLE_PASS(DisableEarlyIfConversion, EarlyIfConverterPass)
524e8d8bef9SDimitry Andric     DISABLE_PASS(DisableEarlyTailDup, EarlyTailDuplicatePass)
525e8d8bef9SDimitry Andric     DISABLE_PASS(DisableMachineCSE, MachineCSEPass)
526e8d8bef9SDimitry Andric     DISABLE_PASS(DisableMachineDCE, DeadMachineInstructionElimPass)
527e8d8bef9SDimitry Andric     DISABLE_PASS(DisableMachineLICM, EarlyMachineLICMPass)
528e8d8bef9SDimitry Andric     DISABLE_PASS(DisableMachineSink, MachineSinkingPass)
529e8d8bef9SDimitry Andric     DISABLE_PASS(DisablePostRAMachineLICM, MachineLICMPass)
530e8d8bef9SDimitry Andric     DISABLE_PASS(DisablePostRAMachineSink, PostRAMachineSinkingPass)
531e8d8bef9SDimitry Andric     DISABLE_PASS(DisablePostRASched, PostRASchedulerPass)
532e8d8bef9SDimitry Andric     DISABLE_PASS(DisableSSC, StackSlotColoringPass)
533e8d8bef9SDimitry Andric     DISABLE_PASS(DisableTailDuplicate, TailDuplicatePass)
534e8d8bef9SDimitry Andric 
535e8d8bef9SDimitry Andric     return true;
536e8d8bef9SDimitry Andric   });
5377a6dacacSDimitry Andric }
538e8d8bef9SDimitry Andric 
5397a6dacacSDimitry Andric Expected<TargetPassConfig::StartStopInfo>
5407a6dacacSDimitry Andric TargetPassConfig::getStartStopInfo(PassInstrumentationCallbacks &PIC) {
5417a6dacacSDimitry Andric   auto [StartBefore, StartBeforeInstanceNum] =
5427a6dacacSDimitry Andric       getPassNameAndInstanceNum(StartBeforeOpt);
5437a6dacacSDimitry Andric   auto [StartAfter, StartAfterInstanceNum] =
5447a6dacacSDimitry Andric       getPassNameAndInstanceNum(StartAfterOpt);
5457a6dacacSDimitry Andric   auto [StopBefore, StopBeforeInstanceNum] =
5467a6dacacSDimitry Andric       getPassNameAndInstanceNum(StopBeforeOpt);
5477a6dacacSDimitry Andric   auto [StopAfter, StopAfterInstanceNum] =
5487a6dacacSDimitry Andric       getPassNameAndInstanceNum(StopAfterOpt);
5497a6dacacSDimitry Andric 
5507a6dacacSDimitry Andric   if (!StartBefore.empty() && !StartAfter.empty())
5517a6dacacSDimitry Andric     return make_error<StringError>(
5527a6dacacSDimitry Andric         Twine(StartBeforeOptName) + " and " + StartAfterOptName + " specified!",
5537a6dacacSDimitry Andric         std::make_error_code(std::errc::invalid_argument));
5547a6dacacSDimitry Andric   if (!StopBefore.empty() && !StopAfter.empty())
5557a6dacacSDimitry Andric     return make_error<StringError>(
5567a6dacacSDimitry Andric         Twine(StopBeforeOptName) + " and " + StopAfterOptName + " specified!",
5577a6dacacSDimitry Andric         std::make_error_code(std::errc::invalid_argument));
5587a6dacacSDimitry Andric 
5597a6dacacSDimitry Andric   StartStopInfo Result;
5607a6dacacSDimitry Andric   Result.StartPass = StartBefore.empty() ? StartAfter : StartBefore;
5617a6dacacSDimitry Andric   Result.StopPass = StopBefore.empty() ? StopAfter : StopBefore;
5627a6dacacSDimitry Andric   Result.StartInstanceNum =
5637a6dacacSDimitry Andric       StartBefore.empty() ? StartAfterInstanceNum : StartBeforeInstanceNum;
5647a6dacacSDimitry Andric   Result.StopInstanceNum =
5657a6dacacSDimitry Andric       StopBefore.empty() ? StopAfterInstanceNum : StopBeforeInstanceNum;
5667a6dacacSDimitry Andric   Result.StartAfter = !StartAfter.empty();
5677a6dacacSDimitry Andric   Result.StopAfter = !StopAfter.empty();
5687a6dacacSDimitry Andric   Result.StartInstanceNum += Result.StartInstanceNum == 0;
5697a6dacacSDimitry Andric   Result.StopInstanceNum += Result.StopInstanceNum == 0;
5707a6dacacSDimitry Andric   return Result;
571e8d8bef9SDimitry Andric }
572e8d8bef9SDimitry Andric 
5730b57cec5SDimitry Andric // Out of line constructor provides default values for pass options and
5740b57cec5SDimitry Andric // registers all common codegen passes.
5750b57cec5SDimitry Andric TargetPassConfig::TargetPassConfig(LLVMTargetMachine &TM, PassManagerBase &pm)
5760b57cec5SDimitry Andric     : ImmutablePass(ID), PM(&pm), TM(&TM) {
5770b57cec5SDimitry Andric   Impl = new PassConfigImpl();
5780b57cec5SDimitry Andric 
5790b57cec5SDimitry Andric   // Register all target independent codegen passes to activate their PassIDs,
5800b57cec5SDimitry Andric   // including this pass itself.
5810b57cec5SDimitry Andric   initializeCodeGen(*PassRegistry::getPassRegistry());
5820b57cec5SDimitry Andric 
5830b57cec5SDimitry Andric   // Also register alias analysis passes required by codegen passes.
5840b57cec5SDimitry Andric   initializeBasicAAWrapperPassPass(*PassRegistry::getPassRegistry());
5850b57cec5SDimitry Andric   initializeAAResultsWrapperPassPass(*PassRegistry::getPassRegistry());
5860b57cec5SDimitry Andric 
5870b57cec5SDimitry Andric   if (EnableIPRA.getNumOccurrences())
5880b57cec5SDimitry Andric     TM.Options.EnableIPRA = EnableIPRA;
5890b57cec5SDimitry Andric   else {
5900b57cec5SDimitry Andric     // If not explicitly specified, use target default.
5910b57cec5SDimitry Andric     TM.Options.EnableIPRA |= TM.useIPRA();
5920b57cec5SDimitry Andric   }
5930b57cec5SDimitry Andric 
5940b57cec5SDimitry Andric   if (TM.Options.EnableIPRA)
5950b57cec5SDimitry Andric     setRequiresCodeGenSCCOrder();
5960b57cec5SDimitry Andric 
5970b57cec5SDimitry Andric   if (EnableGlobalISelAbort.getNumOccurrences())
5980b57cec5SDimitry Andric     TM.Options.GlobalISelAbort = EnableGlobalISelAbort;
5990b57cec5SDimitry Andric 
6000b57cec5SDimitry Andric   setStartStopPasses();
6010b57cec5SDimitry Andric }
6020b57cec5SDimitry Andric 
6035f757f3fSDimitry Andric CodeGenOptLevel TargetPassConfig::getOptLevel() const {
6040b57cec5SDimitry Andric   return TM->getOptLevel();
6050b57cec5SDimitry Andric }
6060b57cec5SDimitry Andric 
6070b57cec5SDimitry Andric /// Insert InsertedPassID pass after TargetPassID.
6080b57cec5SDimitry Andric void TargetPassConfig::insertPass(AnalysisID TargetPassID,
609349cc55cSDimitry Andric                                   IdentifyingPassPtr InsertedPassID) {
6100b57cec5SDimitry Andric   assert(((!InsertedPassID.isInstance() &&
6110b57cec5SDimitry Andric            TargetPassID != InsertedPassID.getID()) ||
6120b57cec5SDimitry Andric           (InsertedPassID.isInstance() &&
6130b57cec5SDimitry Andric            TargetPassID != InsertedPassID.getInstance()->getPassID())) &&
6140b57cec5SDimitry Andric          "Insert a pass after itself!");
615349cc55cSDimitry Andric   Impl->InsertedPasses.emplace_back(TargetPassID, InsertedPassID);
6160b57cec5SDimitry Andric }
6170b57cec5SDimitry Andric 
6180b57cec5SDimitry Andric /// createPassConfig - Create a pass configuration object to be used by
6190b57cec5SDimitry Andric /// addPassToEmitX methods for generating a pipeline of CodeGen passes.
6200b57cec5SDimitry Andric ///
6210b57cec5SDimitry Andric /// Targets may override this to extend TargetPassConfig.
6220b57cec5SDimitry Andric TargetPassConfig *LLVMTargetMachine::createPassConfig(PassManagerBase &PM) {
6230b57cec5SDimitry Andric   return new TargetPassConfig(*this, PM);
6240b57cec5SDimitry Andric }
6250b57cec5SDimitry Andric 
6260b57cec5SDimitry Andric TargetPassConfig::TargetPassConfig()
6270b57cec5SDimitry Andric   : ImmutablePass(ID) {
6280b57cec5SDimitry Andric   report_fatal_error("Trying to construct TargetPassConfig without a target "
6290b57cec5SDimitry Andric                      "machine. Scheduling a CodeGen pass without a target "
6300b57cec5SDimitry Andric                      "triple set?");
6310b57cec5SDimitry Andric }
6320b57cec5SDimitry Andric 
6330b57cec5SDimitry Andric bool TargetPassConfig::willCompleteCodeGenPipeline() {
6340b57cec5SDimitry Andric   return StopBeforeOpt.empty() && StopAfterOpt.empty();
6350b57cec5SDimitry Andric }
6360b57cec5SDimitry Andric 
6370b57cec5SDimitry Andric bool TargetPassConfig::hasLimitedCodeGenPipeline() {
6380b57cec5SDimitry Andric   return !StartBeforeOpt.empty() || !StartAfterOpt.empty() ||
6390b57cec5SDimitry Andric          !willCompleteCodeGenPipeline();
6400b57cec5SDimitry Andric }
6410b57cec5SDimitry Andric 
6427a6dacacSDimitry Andric std::string TargetPassConfig::getLimitedCodeGenPipelineReason() {
6430b57cec5SDimitry Andric   if (!hasLimitedCodeGenPipeline())
6440b57cec5SDimitry Andric     return std::string();
6450b57cec5SDimitry Andric   std::string Res;
6460b57cec5SDimitry Andric   static cl::opt<std::string> *PassNames[] = {&StartAfterOpt, &StartBeforeOpt,
6470b57cec5SDimitry Andric                                               &StopAfterOpt, &StopBeforeOpt};
6480b57cec5SDimitry Andric   static const char *OptNames[] = {StartAfterOptName, StartBeforeOptName,
6490b57cec5SDimitry Andric                                    StopAfterOptName, StopBeforeOptName};
6500b57cec5SDimitry Andric   bool IsFirst = true;
6510b57cec5SDimitry Andric   for (int Idx = 0; Idx < 4; ++Idx)
6520b57cec5SDimitry Andric     if (!PassNames[Idx]->empty()) {
6530b57cec5SDimitry Andric       if (!IsFirst)
6547a6dacacSDimitry Andric         Res += " and ";
6550b57cec5SDimitry Andric       IsFirst = false;
6560b57cec5SDimitry Andric       Res += OptNames[Idx];
6570b57cec5SDimitry Andric     }
6580b57cec5SDimitry Andric   return Res;
6590b57cec5SDimitry Andric }
6600b57cec5SDimitry Andric 
6610b57cec5SDimitry Andric // Helper to verify the analysis is really immutable.
6620b57cec5SDimitry Andric void TargetPassConfig::setOpt(bool &Opt, bool Val) {
6630b57cec5SDimitry Andric   assert(!Initialized && "PassConfig is immutable");
6640b57cec5SDimitry Andric   Opt = Val;
6650b57cec5SDimitry Andric }
6660b57cec5SDimitry Andric 
6670b57cec5SDimitry Andric void TargetPassConfig::substitutePass(AnalysisID StandardID,
6680b57cec5SDimitry Andric                                       IdentifyingPassPtr TargetID) {
6690b57cec5SDimitry Andric   Impl->TargetPasses[StandardID] = TargetID;
6700b57cec5SDimitry Andric }
6710b57cec5SDimitry Andric 
6720b57cec5SDimitry Andric IdentifyingPassPtr TargetPassConfig::getPassSubstitution(AnalysisID ID) const {
6730b57cec5SDimitry Andric   DenseMap<AnalysisID, IdentifyingPassPtr>::const_iterator
6740b57cec5SDimitry Andric     I = Impl->TargetPasses.find(ID);
6750b57cec5SDimitry Andric   if (I == Impl->TargetPasses.end())
6760b57cec5SDimitry Andric     return ID;
6770b57cec5SDimitry Andric   return I->second;
6780b57cec5SDimitry Andric }
6790b57cec5SDimitry Andric 
6800b57cec5SDimitry Andric bool TargetPassConfig::isPassSubstitutedOrOverridden(AnalysisID ID) const {
6810b57cec5SDimitry Andric   IdentifyingPassPtr TargetID = getPassSubstitution(ID);
6820b57cec5SDimitry Andric   IdentifyingPassPtr FinalPtr = overridePass(ID, TargetID);
6830b57cec5SDimitry Andric   return !FinalPtr.isValid() || FinalPtr.isInstance() ||
6840b57cec5SDimitry Andric       FinalPtr.getID() != ID;
6850b57cec5SDimitry Andric }
6860b57cec5SDimitry Andric 
6870b57cec5SDimitry Andric /// Add a pass to the PassManager if that pass is supposed to be run.  If the
6880b57cec5SDimitry Andric /// Started/Stopped flags indicate either that the compilation should start at
6890b57cec5SDimitry Andric /// a later pass or that it should stop after an earlier pass, then do not add
6900b57cec5SDimitry Andric /// the pass.  Finally, compare the current pass against the StartAfter
6910b57cec5SDimitry Andric /// and StopAfter options and change the Started/Stopped flags accordingly.
692349cc55cSDimitry Andric void TargetPassConfig::addPass(Pass *P) {
6930b57cec5SDimitry Andric   assert(!Initialized && "PassConfig is immutable");
6940b57cec5SDimitry Andric 
6950b57cec5SDimitry Andric   // Cache the Pass ID here in case the pass manager finds this pass is
6960b57cec5SDimitry Andric   // redundant with ones already scheduled / available, and deletes it.
6970b57cec5SDimitry Andric   // Fundamentally, once we add the pass to the manager, we no longer own it
6980b57cec5SDimitry Andric   // and shouldn't reference it.
6990b57cec5SDimitry Andric   AnalysisID PassID = P->getPassID();
7000b57cec5SDimitry Andric 
7010b57cec5SDimitry Andric   if (StartBefore == PassID && StartBeforeCount++ == StartBeforeInstanceNum)
7020b57cec5SDimitry Andric     Started = true;
7030b57cec5SDimitry Andric   if (StopBefore == PassID && StopBeforeCount++ == StopBeforeInstanceNum)
7040b57cec5SDimitry Andric     Stopped = true;
7050b57cec5SDimitry Andric   if (Started && !Stopped) {
70681ad6265SDimitry Andric     if (AddingMachinePasses) {
7070b57cec5SDimitry Andric       // Construct banner message before PM->add() as that may delete the pass.
70881ad6265SDimitry Andric       std::string Banner =
70981ad6265SDimitry Andric           std::string("After ") + std::string(P->getPassName());
71081ad6265SDimitry Andric       addMachinePrePasses();
7110b57cec5SDimitry Andric       PM->add(P);
712349cc55cSDimitry Andric       addMachinePostPasses(Banner);
71381ad6265SDimitry Andric     } else {
71481ad6265SDimitry Andric       PM->add(P);
71581ad6265SDimitry Andric     }
7160b57cec5SDimitry Andric 
7170b57cec5SDimitry Andric     // Add the passes after the pass P if there is any.
71881ad6265SDimitry Andric     for (const auto &IP : Impl->InsertedPasses)
7190b57cec5SDimitry Andric       if (IP.TargetPassID == PassID)
720349cc55cSDimitry Andric         addPass(IP.getInsertedPass());
7210b57cec5SDimitry Andric   } else {
7220b57cec5SDimitry Andric     delete P;
7230b57cec5SDimitry Andric   }
7240b57cec5SDimitry Andric 
7250b57cec5SDimitry Andric   if (StopAfter == PassID && StopAfterCount++ == StopAfterInstanceNum)
7260b57cec5SDimitry Andric     Stopped = true;
7270b57cec5SDimitry Andric 
7280b57cec5SDimitry Andric   if (StartAfter == PassID && StartAfterCount++ == StartAfterInstanceNum)
7290b57cec5SDimitry Andric     Started = true;
7300b57cec5SDimitry Andric   if (Stopped && !Started)
7310b57cec5SDimitry Andric     report_fatal_error("Cannot stop compilation after pass that is not run");
7320b57cec5SDimitry Andric }
7330b57cec5SDimitry Andric 
7340b57cec5SDimitry Andric /// Add a CodeGen pass at this point in the pipeline after checking for target
7350b57cec5SDimitry Andric /// and command line overrides.
7360b57cec5SDimitry Andric ///
7370b57cec5SDimitry Andric /// addPass cannot return a pointer to the pass instance because is internal the
7380b57cec5SDimitry Andric /// PassManager and the instance we create here may already be freed.
739349cc55cSDimitry Andric AnalysisID TargetPassConfig::addPass(AnalysisID PassID) {
7400b57cec5SDimitry Andric   IdentifyingPassPtr TargetID = getPassSubstitution(PassID);
7410b57cec5SDimitry Andric   IdentifyingPassPtr FinalPtr = overridePass(PassID, TargetID);
7420b57cec5SDimitry Andric   if (!FinalPtr.isValid())
7430b57cec5SDimitry Andric     return nullptr;
7440b57cec5SDimitry Andric 
7450b57cec5SDimitry Andric   Pass *P;
7460b57cec5SDimitry Andric   if (FinalPtr.isInstance())
7470b57cec5SDimitry Andric     P = FinalPtr.getInstance();
7480b57cec5SDimitry Andric   else {
7490b57cec5SDimitry Andric     P = Pass::createPass(FinalPtr.getID());
7500b57cec5SDimitry Andric     if (!P)
7510b57cec5SDimitry Andric       llvm_unreachable("Pass ID not registered");
7520b57cec5SDimitry Andric   }
7530b57cec5SDimitry Andric   AnalysisID FinalID = P->getPassID();
754349cc55cSDimitry Andric   addPass(P); // Ends the lifetime of P.
7550b57cec5SDimitry Andric 
7560b57cec5SDimitry Andric   return FinalID;
7570b57cec5SDimitry Andric }
7580b57cec5SDimitry Andric 
7590b57cec5SDimitry Andric void TargetPassConfig::printAndVerify(const std::string &Banner) {
7600b57cec5SDimitry Andric   addPrintPass(Banner);
7610b57cec5SDimitry Andric   addVerifyPass(Banner);
7620b57cec5SDimitry Andric }
7630b57cec5SDimitry Andric 
7640b57cec5SDimitry Andric void TargetPassConfig::addPrintPass(const std::string &Banner) {
765e8d8bef9SDimitry Andric   if (PrintAfterISel)
7660b57cec5SDimitry Andric     PM->add(createMachineFunctionPrinterPass(dbgs(), Banner));
7670b57cec5SDimitry Andric }
7680b57cec5SDimitry Andric 
7690b57cec5SDimitry Andric void TargetPassConfig::addVerifyPass(const std::string &Banner) {
7700b57cec5SDimitry Andric   bool Verify = VerifyMachineCode == cl::BOU_TRUE;
7710b57cec5SDimitry Andric #ifdef EXPENSIVE_CHECKS
7720b57cec5SDimitry Andric   if (VerifyMachineCode == cl::BOU_UNSET)
7730b57cec5SDimitry Andric     Verify = TM->isMachineVerifierClean();
7740b57cec5SDimitry Andric #endif
7750b57cec5SDimitry Andric   if (Verify)
7760b57cec5SDimitry Andric     PM->add(createMachineVerifierPass(Banner));
7770b57cec5SDimitry Andric }
7780b57cec5SDimitry Andric 
7795ffd83dbSDimitry Andric void TargetPassConfig::addDebugifyPass() {
7805ffd83dbSDimitry Andric   PM->add(createDebugifyMachineModulePass());
7815ffd83dbSDimitry Andric }
7825ffd83dbSDimitry Andric 
7835ffd83dbSDimitry Andric void TargetPassConfig::addStripDebugPass() {
7845ffd83dbSDimitry Andric   PM->add(createStripDebugMachineModulePass(/*OnlyDebugified=*/true));
7855ffd83dbSDimitry Andric }
7865ffd83dbSDimitry Andric 
787e8d8bef9SDimitry Andric void TargetPassConfig::addCheckDebugPass() {
788e8d8bef9SDimitry Andric   PM->add(createCheckDebugMachineModulePass());
789e8d8bef9SDimitry Andric }
790e8d8bef9SDimitry Andric 
7915ffd83dbSDimitry Andric void TargetPassConfig::addMachinePrePasses(bool AllowDebugify) {
792e8d8bef9SDimitry Andric   if (AllowDebugify && DebugifyIsSafe &&
793e8d8bef9SDimitry Andric       (DebugifyAndStripAll == cl::BOU_TRUE ||
794e8d8bef9SDimitry Andric        DebugifyCheckAndStripAll == cl::BOU_TRUE))
7955ffd83dbSDimitry Andric     addDebugifyPass();
7965ffd83dbSDimitry Andric }
7975ffd83dbSDimitry Andric 
798349cc55cSDimitry Andric void TargetPassConfig::addMachinePostPasses(const std::string &Banner) {
799e8d8bef9SDimitry Andric   if (DebugifyIsSafe) {
800e8d8bef9SDimitry Andric     if (DebugifyCheckAndStripAll == cl::BOU_TRUE) {
801e8d8bef9SDimitry Andric       addCheckDebugPass();
8025ffd83dbSDimitry Andric       addStripDebugPass();
803e8d8bef9SDimitry Andric     } else if (DebugifyAndStripAll == cl::BOU_TRUE)
804e8d8bef9SDimitry Andric       addStripDebugPass();
805e8d8bef9SDimitry Andric   }
8065ffd83dbSDimitry Andric   addVerifyPass(Banner);
8075ffd83dbSDimitry Andric }
8085ffd83dbSDimitry Andric 
8090b57cec5SDimitry Andric /// Add common target configurable passes that perform LLVM IR to IR transforms
8100b57cec5SDimitry Andric /// following machine independent optimization.
8110b57cec5SDimitry Andric void TargetPassConfig::addIRPasses() {
8125ffd83dbSDimitry Andric   // Before running any passes, run the verifier to determine if the input
8135ffd83dbSDimitry Andric   // coming from the front-end and/or optimizer is valid.
8145ffd83dbSDimitry Andric   if (!DisableVerify)
8155ffd83dbSDimitry Andric     addPass(createVerifierPass());
8165ffd83dbSDimitry Andric 
8175f757f3fSDimitry Andric   if (getOptLevel() != CodeGenOptLevel::None) {
8180b57cec5SDimitry Andric     // Basic AliasAnalysis support.
8190b57cec5SDimitry Andric     // Add TypeBasedAliasAnalysis before BasicAliasAnalysis so that
8200b57cec5SDimitry Andric     // BasicAliasAnalysis wins if they disagree. This is intended to help
8210b57cec5SDimitry Andric     // support "obvious" type-punning idioms.
8220b57cec5SDimitry Andric     addPass(createTypeBasedAAWrapperPass());
8230b57cec5SDimitry Andric     addPass(createScopedNoAliasAAWrapperPass());
8240b57cec5SDimitry Andric     addPass(createBasicAAWrapperPass());
8250b57cec5SDimitry Andric 
8260b57cec5SDimitry Andric     // Run loop strength reduction before anything else.
8275ffd83dbSDimitry Andric     if (!DisableLSR) {
8285ffd83dbSDimitry Andric       addPass(createCanonicalizeFreezeInLoopsPass());
8290b57cec5SDimitry Andric       addPass(createLoopStrengthReducePass());
8300b57cec5SDimitry Andric       if (PrintLSR)
8315ffd83dbSDimitry Andric         addPass(createPrintFunctionPass(dbgs(),
8325ffd83dbSDimitry Andric                                         "\n\n*** Code after LSR ***\n"));
8330b57cec5SDimitry Andric     }
8340b57cec5SDimitry Andric 
8350b57cec5SDimitry Andric     // The MergeICmpsPass tries to create memcmp calls by grouping sequences of
8360b57cec5SDimitry Andric     // loads and compares. ExpandMemCmpPass then tries to expand those calls
8370b57cec5SDimitry Andric     // into optimally-sized loads and compares. The transforms are enabled by a
8380b57cec5SDimitry Andric     // target lowering hook.
8390b57cec5SDimitry Andric     if (!DisableMergeICmps)
8400b57cec5SDimitry Andric       addPass(createMergeICmpsLegacyPass());
8415f757f3fSDimitry Andric     addPass(createExpandMemCmpLegacyPass());
8420b57cec5SDimitry Andric   }
8430b57cec5SDimitry Andric 
8440b57cec5SDimitry Andric   // Run GC lowering passes for builtin collectors
8450b57cec5SDimitry Andric   // TODO: add a pass insertion point here
846fe6060f1SDimitry Andric   addPass(&GCLoweringID);
847fe6060f1SDimitry Andric   addPass(&ShadowStackGCLoweringID);
8488bcb0991SDimitry Andric   addPass(createLowerConstantIntrinsicsPass());
8490b57cec5SDimitry Andric 
850bdd1243dSDimitry Andric   // For MachO, lower @llvm.global_dtors into @llvm.global_ctors with
85181ad6265SDimitry Andric   // __cxa_atexit() calls to avoid emitting the deprecated __mod_term_func.
85281ad6265SDimitry Andric   if (TM->getTargetTriple().isOSBinFormatMachO() &&
85306c3fb27SDimitry Andric       !DisableAtExitBasedGlobalDtorLowering)
85481ad6265SDimitry Andric     addPass(createLowerGlobalDtorsLegacyPass());
85581ad6265SDimitry Andric 
8560b57cec5SDimitry Andric   // Make sure that no unreachable blocks are instruction selected.
8570b57cec5SDimitry Andric   addPass(createUnreachableBlockEliminationPass());
8580b57cec5SDimitry Andric 
8590b57cec5SDimitry Andric   // Prepare expensive constants for SelectionDAG.
8605f757f3fSDimitry Andric   if (getOptLevel() != CodeGenOptLevel::None && !DisableConstantHoisting)
8610b57cec5SDimitry Andric     addPass(createConstantHoistingPass());
8620b57cec5SDimitry Andric 
863*0fca6ea1SDimitry Andric   if (getOptLevel() != CodeGenOptLevel::None && !DisableReplaceWithVecLib)
864fe6060f1SDimitry Andric     addPass(createReplaceWithVeclibLegacyPass());
865fe6060f1SDimitry Andric 
8665f757f3fSDimitry Andric   if (getOptLevel() != CodeGenOptLevel::None && !DisablePartialLibcallInlining)
8670b57cec5SDimitry Andric     addPass(createPartiallyInlineLibCallsPass());
8680b57cec5SDimitry Andric 
869fe6060f1SDimitry Andric   // Expand vector predication intrinsics into standard IR instructions.
870fe6060f1SDimitry Andric   // This pass has to run before ScalarizeMaskedMemIntrin and ExpandReduction
871fe6060f1SDimitry Andric   // passes since it emits those kinds of intrinsics.
872fe6060f1SDimitry Andric   addPass(createExpandVectorPredicationPass());
8730b57cec5SDimitry Andric 
874*0fca6ea1SDimitry Andric   // Instrument function entry after all inlining.
875*0fca6ea1SDimitry Andric   addPass(createPostInlineEntryExitInstrumenterPass());
876*0fca6ea1SDimitry Andric 
8770b57cec5SDimitry Andric   // Add scalarization of target's unsupported masked memory intrinsics pass.
8780b57cec5SDimitry Andric   // the unsupported intrinsic will be replaced with a chain of basic blocks,
8790b57cec5SDimitry Andric   // that stores/loads element one-by-one if the appropriate mask bit is set.
880e8d8bef9SDimitry Andric   addPass(createScalarizeMaskedMemIntrinLegacyPass());
8810b57cec5SDimitry Andric 
8820b57cec5SDimitry Andric   // Expand reduction intrinsics into shuffle sequences if the target wants to.
883e8d8bef9SDimitry Andric   // Allow disabling it for testing purposes.
884e8d8bef9SDimitry Andric   if (!DisableExpandReductions)
8850b57cec5SDimitry Andric     addPass(createExpandReductionsPass());
88681ad6265SDimitry Andric 
8875f757f3fSDimitry Andric   if (getOptLevel() != CodeGenOptLevel::None)
88881ad6265SDimitry Andric     addPass(createTLSVariableHoistPass());
88981ad6265SDimitry Andric 
89081ad6265SDimitry Andric   // Convert conditional moves to conditional jumps when profitable.
8915f757f3fSDimitry Andric   if (getOptLevel() != CodeGenOptLevel::None && !DisableSelectOptimize)
89281ad6265SDimitry Andric     addPass(createSelectOptimizePass());
8930b57cec5SDimitry Andric }
8940b57cec5SDimitry Andric 
8950b57cec5SDimitry Andric /// Turn exception handling constructs into something the code generators can
8960b57cec5SDimitry Andric /// handle.
8970b57cec5SDimitry Andric void TargetPassConfig::addPassesToHandleExceptions() {
8980b57cec5SDimitry Andric   const MCAsmInfo *MCAI = TM->getMCAsmInfo();
8990b57cec5SDimitry Andric   assert(MCAI && "No MCAsmInfo");
9000b57cec5SDimitry Andric   switch (MCAI->getExceptionHandlingType()) {
9010b57cec5SDimitry Andric   case ExceptionHandling::SjLj:
9020b57cec5SDimitry Andric     // SjLj piggy-backs on dwarf for this bit. The cleanups done apply to both
9030b57cec5SDimitry Andric     // Dwarf EH prepare needs to be run after SjLj prepare. Otherwise,
9040b57cec5SDimitry Andric     // catch info can get misplaced when a selector ends up more than one block
9050b57cec5SDimitry Andric     // removed from the parent invoke(s). This could happen when a landing
9060b57cec5SDimitry Andric     // pad is shared by multiple invokes and is also a target of a normal
9070b57cec5SDimitry Andric     // edge from elsewhere.
9085ffd83dbSDimitry Andric     addPass(createSjLjEHPreparePass(TM));
909bdd1243dSDimitry Andric     [[fallthrough]];
9100b57cec5SDimitry Andric   case ExceptionHandling::DwarfCFI:
9110b57cec5SDimitry Andric   case ExceptionHandling::ARM:
912e8d8bef9SDimitry Andric   case ExceptionHandling::AIX:
913cb14a3feSDimitry Andric   case ExceptionHandling::ZOS:
9145ffd83dbSDimitry Andric     addPass(createDwarfEHPass(getOptLevel()));
9150b57cec5SDimitry Andric     break;
9160b57cec5SDimitry Andric   case ExceptionHandling::WinEH:
9170b57cec5SDimitry Andric     // We support using both GCC-style and MSVC-style exceptions on Windows, so
9180b57cec5SDimitry Andric     // add both preparation passes. Each pass will only actually run if it
9190b57cec5SDimitry Andric     // recognizes the personality function.
9200b57cec5SDimitry Andric     addPass(createWinEHPass());
9215ffd83dbSDimitry Andric     addPass(createDwarfEHPass(getOptLevel()));
9220b57cec5SDimitry Andric     break;
9230b57cec5SDimitry Andric   case ExceptionHandling::Wasm:
9240b57cec5SDimitry Andric     // Wasm EH uses Windows EH instructions, but it does not need to demote PHIs
9250b57cec5SDimitry Andric     // on catchpads and cleanuppads because it does not outline them into
9260b57cec5SDimitry Andric     // funclets. Catchswitch blocks are not lowered in SelectionDAG, so we
9270b57cec5SDimitry Andric     // should remove PHIs there.
928*0fca6ea1SDimitry Andric     addPass(createWinEHPass(/*DemoteCatchSwitchPHIOnly=*/true));
9290b57cec5SDimitry Andric     addPass(createWasmEHPass());
9300b57cec5SDimitry Andric     break;
9310b57cec5SDimitry Andric   case ExceptionHandling::None:
9320b57cec5SDimitry Andric     addPass(createLowerInvokePass());
9330b57cec5SDimitry Andric 
9340b57cec5SDimitry Andric     // The lower invoke pass may create unreachable code. Remove it.
9350b57cec5SDimitry Andric     addPass(createUnreachableBlockEliminationPass());
9360b57cec5SDimitry Andric     break;
9370b57cec5SDimitry Andric   }
9380b57cec5SDimitry Andric }
9390b57cec5SDimitry Andric 
9400b57cec5SDimitry Andric /// Add pass to prepare the LLVM IR for code generation. This should be done
9410b57cec5SDimitry Andric /// before exception handling preparation passes.
9420b57cec5SDimitry Andric void TargetPassConfig::addCodeGenPrepare() {
9435f757f3fSDimitry Andric   if (getOptLevel() != CodeGenOptLevel::None && !DisableCGP)
9441db9f3b2SDimitry Andric     addPass(createCodeGenPrepareLegacyPass());
9450b57cec5SDimitry Andric }
9460b57cec5SDimitry Andric 
9470b57cec5SDimitry Andric /// Add common passes that perform LLVM IR to IR transforms in preparation for
9480b57cec5SDimitry Andric /// instruction selection.
9490b57cec5SDimitry Andric void TargetPassConfig::addISelPrepare() {
9500b57cec5SDimitry Andric   addPreISel();
9510b57cec5SDimitry Andric 
9520b57cec5SDimitry Andric   // Force codegen to run according to the callgraph.
9530b57cec5SDimitry Andric   if (requiresCodeGenSCCOrder())
9540b57cec5SDimitry Andric     addPass(new DummyCGSCCPass);
9550b57cec5SDimitry Andric 
95606c3fb27SDimitry Andric   addPass(createCallBrPass());
95706c3fb27SDimitry Andric 
9580b57cec5SDimitry Andric   // Add both the safe stack and the stack protection passes: each of them will
9590b57cec5SDimitry Andric   // only protect functions that have corresponding attributes.
9600b57cec5SDimitry Andric   addPass(createSafeStackPass());
9610b57cec5SDimitry Andric   addPass(createStackProtectorPass());
9620b57cec5SDimitry Andric 
9630b57cec5SDimitry Andric   if (PrintISelInput)
9640b57cec5SDimitry Andric     addPass(createPrintFunctionPass(
9650b57cec5SDimitry Andric         dbgs(), "\n\n*** Final LLVM Code input to ISel ***\n"));
9660b57cec5SDimitry Andric 
9670b57cec5SDimitry Andric   // All passes which modify the LLVM IR are now complete; run the verifier
9680b57cec5SDimitry Andric   // to ensure that the IR is valid.
9690b57cec5SDimitry Andric   if (!DisableVerify)
9700b57cec5SDimitry Andric     addPass(createVerifierPass());
9710b57cec5SDimitry Andric }
9720b57cec5SDimitry Andric 
9730b57cec5SDimitry Andric bool TargetPassConfig::addCoreISelPasses() {
9740b57cec5SDimitry Andric   // Enable FastISel with -fast-isel, but allow that to be overridden.
9750b57cec5SDimitry Andric   TM->setO0WantsFastISel(EnableFastISelOption != cl::BOU_FALSE);
9760b57cec5SDimitry Andric 
9770b57cec5SDimitry Andric   // Determine an instruction selector.
9780b57cec5SDimitry Andric   enum class SelectorType { SelectionDAG, FastISel, GlobalISel };
9790b57cec5SDimitry Andric   SelectorType Selector;
9800b57cec5SDimitry Andric 
9810b57cec5SDimitry Andric   if (EnableFastISelOption == cl::BOU_TRUE)
9820b57cec5SDimitry Andric     Selector = SelectorType::FastISel;
9830b57cec5SDimitry Andric   else if (EnableGlobalISelOption == cl::BOU_TRUE ||
9840b57cec5SDimitry Andric            (TM->Options.EnableGlobalISel &&
9850b57cec5SDimitry Andric             EnableGlobalISelOption != cl::BOU_FALSE))
9860b57cec5SDimitry Andric     Selector = SelectorType::GlobalISel;
9875f757f3fSDimitry Andric   else if (TM->getOptLevel() == CodeGenOptLevel::None &&
9885f757f3fSDimitry Andric            TM->getO0WantsFastISel())
9890b57cec5SDimitry Andric     Selector = SelectorType::FastISel;
9900b57cec5SDimitry Andric   else
9910b57cec5SDimitry Andric     Selector = SelectorType::SelectionDAG;
9920b57cec5SDimitry Andric 
9930b57cec5SDimitry Andric   // Set consistently TM->Options.EnableFastISel and EnableGlobalISel.
9940b57cec5SDimitry Andric   if (Selector == SelectorType::FastISel) {
9950b57cec5SDimitry Andric     TM->setFastISel(true);
9960b57cec5SDimitry Andric     TM->setGlobalISel(false);
9970b57cec5SDimitry Andric   } else if (Selector == SelectorType::GlobalISel) {
9980b57cec5SDimitry Andric     TM->setFastISel(false);
9990b57cec5SDimitry Andric     TM->setGlobalISel(true);
10000b57cec5SDimitry Andric   }
10010b57cec5SDimitry Andric 
10025ffd83dbSDimitry Andric   // FIXME: Injecting into the DAGISel pipeline seems to cause issues with
10035ffd83dbSDimitry Andric   //        analyses needing to be re-run. This can result in being unable to
10045ffd83dbSDimitry Andric   //        schedule passes (particularly with 'Function Alias Analysis
10055ffd83dbSDimitry Andric   //        Results'). It's not entirely clear why but AFAICT this seems to be
10065ffd83dbSDimitry Andric   //        due to one FunctionPassManager not being able to use analyses from a
10075ffd83dbSDimitry Andric   //        previous one. As we're injecting a ModulePass we break the usual
10085ffd83dbSDimitry Andric   //        pass manager into two. GlobalISel with the fallback path disabled
10095ffd83dbSDimitry Andric   //        and -run-pass seem to be unaffected. The majority of GlobalISel
10105ffd83dbSDimitry Andric   //        testing uses -run-pass so this probably isn't too bad.
1011bdd1243dSDimitry Andric   SaveAndRestore SavedDebugifyIsSafe(DebugifyIsSafe);
10125ffd83dbSDimitry Andric   if (Selector != SelectorType::GlobalISel || !isGlobalISelAbortEnabled())
10135ffd83dbSDimitry Andric     DebugifyIsSafe = false;
10145ffd83dbSDimitry Andric 
10150b57cec5SDimitry Andric   // Add instruction selector passes.
10160b57cec5SDimitry Andric   if (Selector == SelectorType::GlobalISel) {
1017bdd1243dSDimitry Andric     SaveAndRestore SavedAddingMachinePasses(AddingMachinePasses, true);
10180b57cec5SDimitry Andric     if (addIRTranslator())
10190b57cec5SDimitry Andric       return true;
10200b57cec5SDimitry Andric 
10210b57cec5SDimitry Andric     addPreLegalizeMachineIR();
10220b57cec5SDimitry Andric 
10230b57cec5SDimitry Andric     if (addLegalizeMachineIR())
10240b57cec5SDimitry Andric       return true;
10250b57cec5SDimitry Andric 
10260b57cec5SDimitry Andric     // Before running the register bank selector, ask the target if it
10270b57cec5SDimitry Andric     // wants to run some passes.
10280b57cec5SDimitry Andric     addPreRegBankSelect();
10290b57cec5SDimitry Andric 
10300b57cec5SDimitry Andric     if (addRegBankSelect())
10310b57cec5SDimitry Andric       return true;
10320b57cec5SDimitry Andric 
10330b57cec5SDimitry Andric     addPreGlobalInstructionSelect();
10340b57cec5SDimitry Andric 
10350b57cec5SDimitry Andric     if (addGlobalInstructionSelect())
10360b57cec5SDimitry Andric       return true;
10370b57cec5SDimitry Andric 
10380b57cec5SDimitry Andric     // Pass to reset the MachineFunction if the ISel failed.
10390b57cec5SDimitry Andric     addPass(createResetMachineFunctionPass(
10400b57cec5SDimitry Andric         reportDiagnosticWhenGlobalISelFallback(), isGlobalISelAbortEnabled()));
10410b57cec5SDimitry Andric 
10420b57cec5SDimitry Andric     // Provide a fallback path when we do not want to abort on
10430b57cec5SDimitry Andric     // not-yet-supported input.
10440b57cec5SDimitry Andric     if (!isGlobalISelAbortEnabled() && addInstSelector())
10450b57cec5SDimitry Andric       return true;
10460b57cec5SDimitry Andric 
10470b57cec5SDimitry Andric   } else if (addInstSelector())
10480b57cec5SDimitry Andric     return true;
10490b57cec5SDimitry Andric 
10500b57cec5SDimitry Andric   // Expand pseudo-instructions emitted by ISel. Don't run the verifier before
10510b57cec5SDimitry Andric   // FinalizeISel.
10520b57cec5SDimitry Andric   addPass(&FinalizeISelID);
10530b57cec5SDimitry Andric 
10540b57cec5SDimitry Andric   // Print the instruction selected machine code...
10550b57cec5SDimitry Andric   printAndVerify("After Instruction Selection");
10560b57cec5SDimitry Andric 
10570b57cec5SDimitry Andric   return false;
10580b57cec5SDimitry Andric }
10590b57cec5SDimitry Andric 
10600b57cec5SDimitry Andric bool TargetPassConfig::addISelPasses() {
10610b57cec5SDimitry Andric   if (TM->useEmulatedTLS())
10620b57cec5SDimitry Andric     addPass(createLowerEmuTLSPass());
10630b57cec5SDimitry Andric 
1064e8d8bef9SDimitry Andric   PM->add(createTargetTransformInfoWrapperPass(TM->getTargetIRAnalysis()));
106506c3fb27SDimitry Andric   addPass(createPreISelIntrinsicLoweringPass());
1066bdd1243dSDimitry Andric   addPass(createExpandLargeDivRemPass());
1067bdd1243dSDimitry Andric   addPass(createExpandLargeFpConvertPass());
10680b57cec5SDimitry Andric   addIRPasses();
10690b57cec5SDimitry Andric   addCodeGenPrepare();
10700b57cec5SDimitry Andric   addPassesToHandleExceptions();
10710b57cec5SDimitry Andric   addISelPrepare();
10720b57cec5SDimitry Andric 
10730b57cec5SDimitry Andric   return addCoreISelPasses();
10740b57cec5SDimitry Andric }
10750b57cec5SDimitry Andric 
10760b57cec5SDimitry Andric /// -regalloc=... command line option.
10770b57cec5SDimitry Andric static FunctionPass *useDefaultRegisterAllocator() { return nullptr; }
10780b57cec5SDimitry Andric static cl::opt<RegisterRegAlloc::FunctionPassCtor, false,
10790b57cec5SDimitry Andric                RegisterPassParser<RegisterRegAlloc>>
10800b57cec5SDimitry Andric     RegAlloc("regalloc", cl::Hidden, cl::init(&useDefaultRegisterAllocator),
10810b57cec5SDimitry Andric              cl::desc("Register allocator to use"));
10820b57cec5SDimitry Andric 
10830b57cec5SDimitry Andric /// Add the complete set of target-independent postISel code generator passes.
10840b57cec5SDimitry Andric ///
10850b57cec5SDimitry Andric /// This can be read as the standard order of major LLVM CodeGen stages. Stages
10860b57cec5SDimitry Andric /// with nontrivial configuration or multiple passes are broken out below in
10870b57cec5SDimitry Andric /// add%Stage routines.
10880b57cec5SDimitry Andric ///
10890b57cec5SDimitry Andric /// Any TargetPassConfig::addXX routine may be overriden by the Target. The
10900b57cec5SDimitry Andric /// addPre/Post methods with empty header implementations allow injecting
10910b57cec5SDimitry Andric /// target-specific fixups just before or after major stages. Additionally,
10920b57cec5SDimitry Andric /// targets have the flexibility to change pass order within a stage by
10930b57cec5SDimitry Andric /// overriding default implementation of add%Stage routines below. Each
10940b57cec5SDimitry Andric /// technique has maintainability tradeoffs because alternate pass orders are
10950b57cec5SDimitry Andric /// not well supported. addPre/Post works better if the target pass is easily
10960b57cec5SDimitry Andric /// tied to a common pass. But if it has subtle dependencies on multiple passes,
10970b57cec5SDimitry Andric /// the target should override the stage instead.
10980b57cec5SDimitry Andric ///
10990b57cec5SDimitry Andric /// TODO: We could use a single addPre/Post(ID) hook to allow pass injection
11000b57cec5SDimitry Andric /// before/after any target-independent pass. But it's currently overkill.
11010b57cec5SDimitry Andric void TargetPassConfig::addMachinePasses() {
11020b57cec5SDimitry Andric   AddingMachinePasses = true;
11030b57cec5SDimitry Andric 
11040b57cec5SDimitry Andric   // Add passes that optimize machine instructions in SSA form.
11055f757f3fSDimitry Andric   if (getOptLevel() != CodeGenOptLevel::None) {
11060b57cec5SDimitry Andric     addMachineSSAOptimization();
11070b57cec5SDimitry Andric   } else {
11080b57cec5SDimitry Andric     // If the target requests it, assign local variables to stack slots relative
11090b57cec5SDimitry Andric     // to one another and simplify frame index references where possible.
11105ffd83dbSDimitry Andric     addPass(&LocalStackSlotAllocationID);
11110b57cec5SDimitry Andric   }
11120b57cec5SDimitry Andric 
11130b57cec5SDimitry Andric   if (TM->Options.EnableIPRA)
11140b57cec5SDimitry Andric     addPass(createRegUsageInfoPropPass());
11150b57cec5SDimitry Andric 
11160b57cec5SDimitry Andric   // Run pre-ra passes.
11170b57cec5SDimitry Andric   addPreRegAlloc();
11180b57cec5SDimitry Andric 
11195ffd83dbSDimitry Andric   // Debugifying the register allocator passes seems to provoke some
11205ffd83dbSDimitry Andric   // non-determinism that affects CodeGen and there doesn't seem to be a point
11215ffd83dbSDimitry Andric   // where it becomes safe again so stop debugifying here.
11225ffd83dbSDimitry Andric   DebugifyIsSafe = false;
11235ffd83dbSDimitry Andric 
1124349cc55cSDimitry Andric   // Add a FSDiscriminator pass right before RA, so that we could get
1125349cc55cSDimitry Andric   // more precise SampleFDO profile for RA.
1126349cc55cSDimitry Andric   if (EnableFSDiscriminator) {
1127349cc55cSDimitry Andric     addPass(createMIRAddFSDiscriminatorsPass(
1128349cc55cSDimitry Andric         sampleprof::FSDiscriminatorPass::Pass1));
1129349cc55cSDimitry Andric     const std::string ProfileFile = getFSProfileFile(TM);
1130349cc55cSDimitry Andric     if (!ProfileFile.empty() && !DisableRAFSProfileLoader)
113106c3fb27SDimitry Andric       addPass(createMIRProfileLoaderPass(ProfileFile, getFSRemappingFile(TM),
113206c3fb27SDimitry Andric                                          sampleprof::FSDiscriminatorPass::Pass1,
113306c3fb27SDimitry Andric                                          nullptr));
1134349cc55cSDimitry Andric   }
1135349cc55cSDimitry Andric 
11360b57cec5SDimitry Andric   // Run register allocation and passes that are tightly coupled with it,
11370b57cec5SDimitry Andric   // including phi elimination and scheduling.
11380b57cec5SDimitry Andric   if (getOptimizeRegAlloc())
11390b57cec5SDimitry Andric     addOptimizedRegAlloc();
11400b57cec5SDimitry Andric   else
11410b57cec5SDimitry Andric     addFastRegAlloc();
11420b57cec5SDimitry Andric 
11430b57cec5SDimitry Andric   // Run post-ra passes.
11440b57cec5SDimitry Andric   addPostRegAlloc();
11450b57cec5SDimitry Andric 
1146349cc55cSDimitry Andric   addPass(&RemoveRedundantDebugValuesID);
1147fe6060f1SDimitry Andric 
11485ffd83dbSDimitry Andric   addPass(&FixupStatepointCallerSavedID);
11495ffd83dbSDimitry Andric 
11500b57cec5SDimitry Andric   // Insert prolog/epilog code.  Eliminate abstract frame index references...
11515f757f3fSDimitry Andric   if (getOptLevel() != CodeGenOptLevel::None) {
11520b57cec5SDimitry Andric     addPass(&PostRAMachineSinkingID);
11530b57cec5SDimitry Andric     addPass(&ShrinkWrapID);
11540b57cec5SDimitry Andric   }
11550b57cec5SDimitry Andric 
11560b57cec5SDimitry Andric   // Prolog/Epilog inserter needs a TargetMachine to instantiate. But only
11570b57cec5SDimitry Andric   // do so if it hasn't been disabled, substituted, or overridden.
11580b57cec5SDimitry Andric   if (!isPassSubstitutedOrOverridden(&PrologEpilogCodeInserterID))
11590b57cec5SDimitry Andric       addPass(createPrologEpilogInserterPass());
11600b57cec5SDimitry Andric 
11610b57cec5SDimitry Andric   /// Add passes that optimize machine instructions after register allocation.
11625f757f3fSDimitry Andric   if (getOptLevel() != CodeGenOptLevel::None)
11630b57cec5SDimitry Andric       addMachineLateOptimization();
11640b57cec5SDimitry Andric 
11650b57cec5SDimitry Andric   // Expand pseudo instructions before second scheduling pass.
11660b57cec5SDimitry Andric   addPass(&ExpandPostRAPseudosID);
11670b57cec5SDimitry Andric 
11680b57cec5SDimitry Andric   // Run pre-sched2 passes.
11690b57cec5SDimitry Andric   addPreSched2();
11700b57cec5SDimitry Andric 
11710b57cec5SDimitry Andric   if (EnableImplicitNullChecks)
11720b57cec5SDimitry Andric     addPass(&ImplicitNullChecksID);
11730b57cec5SDimitry Andric 
11740b57cec5SDimitry Andric   // Second pass scheduler.
11750b57cec5SDimitry Andric   // Let Target optionally insert this pass by itself at some other
11760b57cec5SDimitry Andric   // point.
11775f757f3fSDimitry Andric   if (getOptLevel() != CodeGenOptLevel::None &&
11780b57cec5SDimitry Andric       !TM->targetSchedulesPostRAScheduling()) {
11790b57cec5SDimitry Andric     if (MISchedPostRA)
11800b57cec5SDimitry Andric       addPass(&PostMachineSchedulerID);
11810b57cec5SDimitry Andric     else
11820b57cec5SDimitry Andric       addPass(&PostRASchedulerID);
11830b57cec5SDimitry Andric   }
11840b57cec5SDimitry Andric 
11850b57cec5SDimitry Andric   // GC
11865f757f3fSDimitry Andric   addGCPasses();
11870b57cec5SDimitry Andric 
11880b57cec5SDimitry Andric   // Basic block placement.
11895f757f3fSDimitry Andric   if (getOptLevel() != CodeGenOptLevel::None)
11900b57cec5SDimitry Andric     addBlockPlacement();
11910b57cec5SDimitry Andric 
119255e4f9d5SDimitry Andric   // Insert before XRay Instrumentation.
11935ffd83dbSDimitry Andric   addPass(&FEntryInserterID);
119455e4f9d5SDimitry Andric 
11955ffd83dbSDimitry Andric   addPass(&XRayInstrumentationID);
11965ffd83dbSDimitry Andric   addPass(&PatchableFunctionID);
119755e4f9d5SDimitry Andric 
11980b57cec5SDimitry Andric   addPreEmitPass();
11990b57cec5SDimitry Andric 
12000b57cec5SDimitry Andric   if (TM->Options.EnableIPRA)
12010b57cec5SDimitry Andric     // Collect register usage information and produce a register mask of
12020b57cec5SDimitry Andric     // clobbered registers, to be used to optimize call sites.
12030b57cec5SDimitry Andric     addPass(createRegUsageInfoCollector());
12040b57cec5SDimitry Andric 
12055ffd83dbSDimitry Andric   // FIXME: Some backends are incompatible with running the verifier after
12065ffd83dbSDimitry Andric   // addPreEmitPass.  Maybe only pass "false" here for those targets?
1207349cc55cSDimitry Andric   addPass(&FuncletLayoutID);
12080b57cec5SDimitry Andric 
1209349cc55cSDimitry Andric   addPass(&StackMapLivenessID);
1210349cc55cSDimitry Andric   addPass(&LiveDebugValuesID);
1211bdd1243dSDimitry Andric   addPass(&MachineSanitizerBinaryMetadataID);
12120b57cec5SDimitry Andric 
12135f757f3fSDimitry Andric   if (TM->Options.EnableMachineOutliner &&
12145f757f3fSDimitry Andric       getOptLevel() != CodeGenOptLevel::None &&
1215e8d8bef9SDimitry Andric       EnableMachineOutliner != RunOutliner::NeverOutline) {
1216e8d8bef9SDimitry Andric     bool RunOnAllFunctions =
1217e8d8bef9SDimitry Andric         (EnableMachineOutliner == RunOutliner::AlwaysOutline);
1218e8d8bef9SDimitry Andric     bool AddOutliner =
1219e8d8bef9SDimitry Andric         RunOnAllFunctions || TM->Options.SupportsDefaultOutlining;
12200b57cec5SDimitry Andric     if (AddOutliner)
12210b57cec5SDimitry Andric       addPass(createMachineOutlinerPass(RunOnAllFunctions));
12220b57cec5SDimitry Andric   }
12230b57cec5SDimitry Andric 
12245f757f3fSDimitry Andric   if (GCEmptyBlocks)
12255f757f3fSDimitry Andric     addPass(llvm::createGCEmptyBasicBlocksPass());
12265f757f3fSDimitry Andric 
122706c3fb27SDimitry Andric   if (EnableFSDiscriminator)
122806c3fb27SDimitry Andric     addPass(createMIRAddFSDiscriminatorsPass(
122906c3fb27SDimitry Andric         sampleprof::FSDiscriminatorPass::PassLast));
123006c3fb27SDimitry Andric 
1231*0fca6ea1SDimitry Andric   bool NeedsBBSections =
1232*0fca6ea1SDimitry Andric       TM->getBBSectionsType() != llvm::BasicBlockSection::None;
1233e8d8bef9SDimitry Andric   // Machine function splitter uses the basic block sections feature. Both
1234*0fca6ea1SDimitry Andric   // cannot be enabled at the same time. We do not apply machine function
1235*0fca6ea1SDimitry Andric   // splitter if -basic-block-sections is requested.
1236*0fca6ea1SDimitry Andric   if (!NeedsBBSections && (TM->Options.EnableMachineFunctionSplitter ||
1237*0fca6ea1SDimitry Andric                            EnableMachineFunctionSplitter)) {
123806c3fb27SDimitry Andric     const std::string ProfileFile = getFSProfileFile(TM);
123906c3fb27SDimitry Andric     if (!ProfileFile.empty()) {
124006c3fb27SDimitry Andric       if (EnableFSDiscriminator) {
124106c3fb27SDimitry Andric         addPass(createMIRProfileLoaderPass(
124206c3fb27SDimitry Andric             ProfileFile, getFSRemappingFile(TM),
124306c3fb27SDimitry Andric             sampleprof::FSDiscriminatorPass::PassLast, nullptr));
124406c3fb27SDimitry Andric       } else {
124506c3fb27SDimitry Andric         // Sample profile is given, but FSDiscriminator is not
124606c3fb27SDimitry Andric         // enabled, this may result in performance regression.
124706c3fb27SDimitry Andric         WithColor::warning()
124806c3fb27SDimitry Andric             << "Using AutoFDO without FSDiscriminator for MFS may regress "
12497a6dacacSDimitry Andric                "performance.\n";
125006c3fb27SDimitry Andric       }
125106c3fb27SDimitry Andric     }
1252e8d8bef9SDimitry Andric     addPass(createMachineFunctionSplitterPass());
1253e8d8bef9SDimitry Andric   }
1254*0fca6ea1SDimitry Andric   // We run the BasicBlockSections pass if either we need BB sections or BB
1255*0fca6ea1SDimitry Andric   // address map (or both).
1256*0fca6ea1SDimitry Andric   if (NeedsBBSections || TM->Options.BBAddrMap) {
1257*0fca6ea1SDimitry Andric     if (TM->getBBSectionsType() == llvm::BasicBlockSection::List) {
1258*0fca6ea1SDimitry Andric       addPass(llvm::createBasicBlockSectionsProfileReaderWrapperPass(
1259*0fca6ea1SDimitry Andric           TM->getBBSectionsFuncListBuf()));
1260*0fca6ea1SDimitry Andric       addPass(llvm::createBasicBlockPathCloningPass());
1261*0fca6ea1SDimitry Andric     }
1262*0fca6ea1SDimitry Andric     addPass(llvm::createBasicBlockSectionsPass());
1263*0fca6ea1SDimitry Andric   }
12645ffd83dbSDimitry Andric 
126506c3fb27SDimitry Andric   addPostBBSections();
126606c3fb27SDimitry Andric 
126781ad6265SDimitry Andric   if (!DisableCFIFixup && TM->Options.EnableCFIFixup)
126881ad6265SDimitry Andric     addPass(createCFIFixup());
126981ad6265SDimitry Andric 
1270bdd1243dSDimitry Andric   PM->add(createStackFrameLayoutAnalysisPass());
1271bdd1243dSDimitry Andric 
12720b57cec5SDimitry Andric   // Add passes that directly emit MI after all other MI passes.
12730b57cec5SDimitry Andric   addPreEmitPass2();
12740b57cec5SDimitry Andric 
12750b57cec5SDimitry Andric   AddingMachinePasses = false;
12760b57cec5SDimitry Andric }
12770b57cec5SDimitry Andric 
12780b57cec5SDimitry Andric /// Add passes that optimize machine instructions in SSA form.
12790b57cec5SDimitry Andric void TargetPassConfig::addMachineSSAOptimization() {
12800b57cec5SDimitry Andric   // Pre-ra tail duplication.
12810b57cec5SDimitry Andric   addPass(&EarlyTailDuplicateID);
12820b57cec5SDimitry Andric 
12830b57cec5SDimitry Andric   // Optimize PHIs before DCE: removing dead PHI cycles may make more
12840b57cec5SDimitry Andric   // instructions dead.
12855ffd83dbSDimitry Andric   addPass(&OptimizePHIsID);
12860b57cec5SDimitry Andric 
12870b57cec5SDimitry Andric   // This pass merges large allocas. StackSlotColoring is a different pass
12880b57cec5SDimitry Andric   // which merges spill slots.
12895ffd83dbSDimitry Andric   addPass(&StackColoringID);
12900b57cec5SDimitry Andric 
12910b57cec5SDimitry Andric   // If the target requests it, assign local variables to stack slots relative
12920b57cec5SDimitry Andric   // to one another and simplify frame index references where possible.
12935ffd83dbSDimitry Andric   addPass(&LocalStackSlotAllocationID);
12940b57cec5SDimitry Andric 
12950b57cec5SDimitry Andric   // With optimization, dead code should already be eliminated. However
12960b57cec5SDimitry Andric   // there is one known exception: lowered code for arguments that are only
12970b57cec5SDimitry Andric   // used by tail calls, where the tail calls reuse the incoming stack
12980b57cec5SDimitry Andric   // arguments directly (see t11 in test/CodeGen/X86/sibcall.ll).
12990b57cec5SDimitry Andric   addPass(&DeadMachineInstructionElimID);
13000b57cec5SDimitry Andric 
13010b57cec5SDimitry Andric   // Allow targets to insert passes that improve instruction level parallelism,
13020b57cec5SDimitry Andric   // like if-conversion. Such passes will typically need dominator trees and
13030b57cec5SDimitry Andric   // loop info, just like LICM and CSE below.
13040b57cec5SDimitry Andric   addILPOpts();
13050b57cec5SDimitry Andric 
13065ffd83dbSDimitry Andric   addPass(&EarlyMachineLICMID);
13075ffd83dbSDimitry Andric   addPass(&MachineCSEID);
13080b57cec5SDimitry Andric 
13090b57cec5SDimitry Andric   addPass(&MachineSinkingID);
13100b57cec5SDimitry Andric 
13110b57cec5SDimitry Andric   addPass(&PeepholeOptimizerID);
13120b57cec5SDimitry Andric   // Clean-up the dead code that may have been generated by peephole
13130b57cec5SDimitry Andric   // rewriting.
13140b57cec5SDimitry Andric   addPass(&DeadMachineInstructionElimID);
13150b57cec5SDimitry Andric }
13160b57cec5SDimitry Andric 
13170b57cec5SDimitry Andric //===---------------------------------------------------------------------===//
13180b57cec5SDimitry Andric /// Register Allocation Pass Configuration
13190b57cec5SDimitry Andric //===---------------------------------------------------------------------===//
13200b57cec5SDimitry Andric 
13210b57cec5SDimitry Andric bool TargetPassConfig::getOptimizeRegAlloc() const {
13220b57cec5SDimitry Andric   switch (OptimizeRegAlloc) {
13235f757f3fSDimitry Andric   case cl::BOU_UNSET:
13245f757f3fSDimitry Andric     return getOptLevel() != CodeGenOptLevel::None;
13250b57cec5SDimitry Andric   case cl::BOU_TRUE:  return true;
13260b57cec5SDimitry Andric   case cl::BOU_FALSE: return false;
13270b57cec5SDimitry Andric   }
13280b57cec5SDimitry Andric   llvm_unreachable("Invalid optimize-regalloc state");
13290b57cec5SDimitry Andric }
13300b57cec5SDimitry Andric 
13310b57cec5SDimitry Andric /// A dummy default pass factory indicates whether the register allocator is
13320b57cec5SDimitry Andric /// overridden on the command line.
13330b57cec5SDimitry Andric static llvm::once_flag InitializeDefaultRegisterAllocatorFlag;
13340b57cec5SDimitry Andric 
13350b57cec5SDimitry Andric static RegisterRegAlloc
13360b57cec5SDimitry Andric defaultRegAlloc("default",
13370b57cec5SDimitry Andric                 "pick register allocator based on -O option",
13380b57cec5SDimitry Andric                 useDefaultRegisterAllocator);
13390b57cec5SDimitry Andric 
13400b57cec5SDimitry Andric static void initializeDefaultRegisterAllocatorOnce() {
13410b57cec5SDimitry Andric   if (!RegisterRegAlloc::getDefault())
13420b57cec5SDimitry Andric     RegisterRegAlloc::setDefault(RegAlloc);
13430b57cec5SDimitry Andric }
13440b57cec5SDimitry Andric 
13450b57cec5SDimitry Andric /// Instantiate the default register allocator pass for this target for either
13460b57cec5SDimitry Andric /// the optimized or unoptimized allocation path. This will be added to the pass
13470b57cec5SDimitry Andric /// manager by addFastRegAlloc in the unoptimized case or addOptimizedRegAlloc
13480b57cec5SDimitry Andric /// in the optimized case.
13490b57cec5SDimitry Andric ///
13500b57cec5SDimitry Andric /// A target that uses the standard regalloc pass order for fast or optimized
13510b57cec5SDimitry Andric /// allocation may still override this for per-target regalloc
13520b57cec5SDimitry Andric /// selection. But -regalloc=... always takes precedence.
13530b57cec5SDimitry Andric FunctionPass *TargetPassConfig::createTargetRegisterAllocator(bool Optimized) {
13540b57cec5SDimitry Andric   if (Optimized)
13550b57cec5SDimitry Andric     return createGreedyRegisterAllocator();
13560b57cec5SDimitry Andric   else
13570b57cec5SDimitry Andric     return createFastRegisterAllocator();
13580b57cec5SDimitry Andric }
13590b57cec5SDimitry Andric 
13600b57cec5SDimitry Andric /// Find and instantiate the register allocation pass requested by this target
13610b57cec5SDimitry Andric /// at the current optimization level.  Different register allocators are
13620b57cec5SDimitry Andric /// defined as separate passes because they may require different analysis.
13630b57cec5SDimitry Andric ///
13640b57cec5SDimitry Andric /// This helper ensures that the regalloc= option is always available,
13650b57cec5SDimitry Andric /// even for targets that override the default allocator.
13660b57cec5SDimitry Andric ///
13670b57cec5SDimitry Andric /// FIXME: When MachinePassRegistry register pass IDs instead of function ptrs,
13680b57cec5SDimitry Andric /// this can be folded into addPass.
13690b57cec5SDimitry Andric FunctionPass *TargetPassConfig::createRegAllocPass(bool Optimized) {
13700b57cec5SDimitry Andric   // Initialize the global default.
13710b57cec5SDimitry Andric   llvm::call_once(InitializeDefaultRegisterAllocatorFlag,
13720b57cec5SDimitry Andric                   initializeDefaultRegisterAllocatorOnce);
13730b57cec5SDimitry Andric 
13740b57cec5SDimitry Andric   RegisterRegAlloc::FunctionPassCtor Ctor = RegisterRegAlloc::getDefault();
13750b57cec5SDimitry Andric   if (Ctor != useDefaultRegisterAllocator)
13760b57cec5SDimitry Andric     return Ctor();
13770b57cec5SDimitry Andric 
13780b57cec5SDimitry Andric   // With no -regalloc= override, ask the target for a regalloc pass.
13790b57cec5SDimitry Andric   return createTargetRegisterAllocator(Optimized);
13800b57cec5SDimitry Andric }
13810b57cec5SDimitry Andric 
138281ad6265SDimitry Andric bool TargetPassConfig::isCustomizedRegAlloc() {
138381ad6265SDimitry Andric   return RegAlloc !=
138481ad6265SDimitry Andric          (RegisterRegAlloc::FunctionPassCtor)&useDefaultRegisterAllocator;
138581ad6265SDimitry Andric }
138681ad6265SDimitry Andric 
1387e8d8bef9SDimitry Andric bool TargetPassConfig::addRegAssignAndRewriteFast() {
1388fe6060f1SDimitry Andric   if (RegAlloc != (RegisterRegAlloc::FunctionPassCtor)&useDefaultRegisterAllocator &&
1389fe6060f1SDimitry Andric       RegAlloc != (RegisterRegAlloc::FunctionPassCtor)&createFastRegisterAllocator)
13900b57cec5SDimitry Andric     report_fatal_error("Must use fast (default) register allocator for unoptimized regalloc.");
13910b57cec5SDimitry Andric 
13920b57cec5SDimitry Andric   addPass(createRegAllocPass(false));
1393fe6060f1SDimitry Andric 
1394fe6060f1SDimitry Andric   // Allow targets to change the register assignments after
1395fe6060f1SDimitry Andric   // fast register allocation.
1396fe6060f1SDimitry Andric   addPostFastRegAllocRewrite();
13970b57cec5SDimitry Andric   return true;
13980b57cec5SDimitry Andric }
13990b57cec5SDimitry Andric 
1400e8d8bef9SDimitry Andric bool TargetPassConfig::addRegAssignAndRewriteOptimized() {
14010b57cec5SDimitry Andric   // Add the selected register allocation pass.
14020b57cec5SDimitry Andric   addPass(createRegAllocPass(true));
14030b57cec5SDimitry Andric 
14040b57cec5SDimitry Andric   // Allow targets to change the register assignments before rewriting.
14050b57cec5SDimitry Andric   addPreRewrite();
14060b57cec5SDimitry Andric 
14070b57cec5SDimitry Andric   // Finally rewrite virtual registers.
14080b57cec5SDimitry Andric   addPass(&VirtRegRewriterID);
14095ffd83dbSDimitry Andric 
141004eeddc0SDimitry Andric   // Regalloc scoring for ML-driven eviction - noop except when learning a new
141104eeddc0SDimitry Andric   // eviction policy.
141204eeddc0SDimitry Andric   addPass(createRegAllocScoringPass());
14130b57cec5SDimitry Andric   return true;
14140b57cec5SDimitry Andric }
14150b57cec5SDimitry Andric 
14160b57cec5SDimitry Andric /// Return true if the default global register allocator is in use and
14170b57cec5SDimitry Andric /// has not be overriden on the command line with '-regalloc=...'
14180b57cec5SDimitry Andric bool TargetPassConfig::usingDefaultRegAlloc() const {
14190b57cec5SDimitry Andric   return RegAlloc.getNumOccurrences() == 0;
14200b57cec5SDimitry Andric }
14210b57cec5SDimitry Andric 
14220b57cec5SDimitry Andric /// Add the minimum set of target-independent passes that are required for
14230b57cec5SDimitry Andric /// register allocation. No coalescing or scheduling.
14240b57cec5SDimitry Andric void TargetPassConfig::addFastRegAlloc() {
1425349cc55cSDimitry Andric   addPass(&PHIEliminationID);
1426349cc55cSDimitry Andric   addPass(&TwoAddressInstructionPassID);
14270b57cec5SDimitry Andric 
1428e8d8bef9SDimitry Andric   addRegAssignAndRewriteFast();
14290b57cec5SDimitry Andric }
14300b57cec5SDimitry Andric 
14310b57cec5SDimitry Andric /// Add standard target-independent passes that are tightly coupled with
14320b57cec5SDimitry Andric /// optimized register allocation, including coalescing, machine instruction
14330b57cec5SDimitry Andric /// scheduling, and register allocation itself.
14340b57cec5SDimitry Andric void TargetPassConfig::addOptimizedRegAlloc() {
1435349cc55cSDimitry Andric   addPass(&DetectDeadLanesID);
14360b57cec5SDimitry Andric 
1437*0fca6ea1SDimitry Andric   addPass(&InitUndefID);
1438*0fca6ea1SDimitry Andric 
1439349cc55cSDimitry Andric   addPass(&ProcessImplicitDefsID);
14400b57cec5SDimitry Andric 
14410b57cec5SDimitry Andric   // LiveVariables currently requires pure SSA form.
14420b57cec5SDimitry Andric   //
14430b57cec5SDimitry Andric   // FIXME: Once TwoAddressInstruction pass no longer uses kill flags,
14440b57cec5SDimitry Andric   // LiveVariables can be removed completely, and LiveIntervals can be directly
14450b57cec5SDimitry Andric   // computed. (We still either need to regenerate kill flags after regalloc, or
14460b57cec5SDimitry Andric   // preferably fix the scavenger to not depend on them).
1447e8d8bef9SDimitry Andric   // FIXME: UnreachableMachineBlockElim is a dependant pass of LiveVariables.
1448e8d8bef9SDimitry Andric   // When LiveVariables is removed this has to be removed/moved either.
1449e8d8bef9SDimitry Andric   // Explicit addition of UnreachableMachineBlockElim allows stopping before or
1450e8d8bef9SDimitry Andric   // after it with -stop-before/-stop-after.
1451349cc55cSDimitry Andric   addPass(&UnreachableMachineBlockElimID);
1452349cc55cSDimitry Andric   addPass(&LiveVariablesID);
14530b57cec5SDimitry Andric 
14540b57cec5SDimitry Andric   // Edge splitting is smarter with machine loop info.
1455349cc55cSDimitry Andric   addPass(&MachineLoopInfoID);
1456349cc55cSDimitry Andric   addPass(&PHIEliminationID);
14570b57cec5SDimitry Andric 
14580b57cec5SDimitry Andric   // Eventually, we want to run LiveIntervals before PHI elimination.
14590b57cec5SDimitry Andric   if (EarlyLiveIntervals)
1460349cc55cSDimitry Andric     addPass(&LiveIntervalsID);
14610b57cec5SDimitry Andric 
1462349cc55cSDimitry Andric   addPass(&TwoAddressInstructionPassID);
14630b57cec5SDimitry Andric   addPass(&RegisterCoalescerID);
14640b57cec5SDimitry Andric 
14650b57cec5SDimitry Andric   // The machine scheduler may accidentally create disconnected components
14660b57cec5SDimitry Andric   // when moving subregister definitions around, avoid this by splitting them to
14670b57cec5SDimitry Andric   // separate vregs before. Splitting can also improve reg. allocation quality.
14680b57cec5SDimitry Andric   addPass(&RenameIndependentSubregsID);
14690b57cec5SDimitry Andric 
14700b57cec5SDimitry Andric   // PreRA instruction scheduling.
14710b57cec5SDimitry Andric   addPass(&MachineSchedulerID);
14720b57cec5SDimitry Andric 
1473e8d8bef9SDimitry Andric   if (addRegAssignAndRewriteOptimized()) {
1474e8d8bef9SDimitry Andric     // Perform stack slot coloring and post-ra machine LICM.
1475e8d8bef9SDimitry Andric     addPass(&StackSlotColoringID);
1476e8d8bef9SDimitry Andric 
14770b57cec5SDimitry Andric     // Allow targets to expand pseudo instructions depending on the choice of
14780b57cec5SDimitry Andric     // registers before MachineCopyPropagation.
14790b57cec5SDimitry Andric     addPostRewrite();
14800b57cec5SDimitry Andric 
14810b57cec5SDimitry Andric     // Copy propagate to forward register uses and try to eliminate COPYs that
14820b57cec5SDimitry Andric     // were not coalesced.
14830b57cec5SDimitry Andric     addPass(&MachineCopyPropagationID);
14840b57cec5SDimitry Andric 
14850b57cec5SDimitry Andric     // Run post-ra machine LICM to hoist reloads / remats.
14860b57cec5SDimitry Andric     //
14870b57cec5SDimitry Andric     // FIXME: can this move into MachineLateOptimization?
14880b57cec5SDimitry Andric     addPass(&MachineLICMID);
14890b57cec5SDimitry Andric   }
14900b57cec5SDimitry Andric }
14910b57cec5SDimitry Andric 
14920b57cec5SDimitry Andric //===---------------------------------------------------------------------===//
14930b57cec5SDimitry Andric /// Post RegAlloc Pass Configuration
14940b57cec5SDimitry Andric //===---------------------------------------------------------------------===//
14950b57cec5SDimitry Andric 
14960b57cec5SDimitry Andric /// Add passes that optimize machine instructions after register allocation.
14970b57cec5SDimitry Andric void TargetPassConfig::addMachineLateOptimization() {
1498bdd1243dSDimitry Andric   // Cleanup of redundant immediate/address loads.
1499bdd1243dSDimitry Andric   addPass(&MachineLateInstrsCleanupID);
1500bdd1243dSDimitry Andric 
15010b57cec5SDimitry Andric   // Branch folding must be run after regalloc and prolog/epilog insertion.
15020b57cec5SDimitry Andric   addPass(&BranchFolderPassID);
15030b57cec5SDimitry Andric 
15040b57cec5SDimitry Andric   // Tail duplication.
15050b57cec5SDimitry Andric   // Note that duplicating tail just increases code size and degrades
15060b57cec5SDimitry Andric   // performance for targets that require Structured Control Flow.
15070b57cec5SDimitry Andric   // In addition it can also make CFG irreducible. Thus we disable it.
15080b57cec5SDimitry Andric   if (!TM->requiresStructuredCFG())
15090b57cec5SDimitry Andric     addPass(&TailDuplicateID);
15100b57cec5SDimitry Andric 
15110b57cec5SDimitry Andric   // Copy propagation.
15120b57cec5SDimitry Andric   addPass(&MachineCopyPropagationID);
15130b57cec5SDimitry Andric }
15140b57cec5SDimitry Andric 
15150b57cec5SDimitry Andric /// Add standard GC passes.
15160b57cec5SDimitry Andric bool TargetPassConfig::addGCPasses() {
1517349cc55cSDimitry Andric   addPass(&GCMachineCodeAnalysisID);
15180b57cec5SDimitry Andric   return true;
15190b57cec5SDimitry Andric }
15200b57cec5SDimitry Andric 
15210b57cec5SDimitry Andric /// Add standard basic block placement passes.
15220b57cec5SDimitry Andric void TargetPassConfig::addBlockPlacement() {
1523349cc55cSDimitry Andric   if (EnableFSDiscriminator) {
1524349cc55cSDimitry Andric     addPass(createMIRAddFSDiscriminatorsPass(
1525349cc55cSDimitry Andric         sampleprof::FSDiscriminatorPass::Pass2));
1526349cc55cSDimitry Andric     const std::string ProfileFile = getFSProfileFile(TM);
1527349cc55cSDimitry Andric     if (!ProfileFile.empty() && !DisableLayoutFSProfileLoader)
152806c3fb27SDimitry Andric       addPass(createMIRProfileLoaderPass(ProfileFile, getFSRemappingFile(TM),
152906c3fb27SDimitry Andric                                          sampleprof::FSDiscriminatorPass::Pass2,
153006c3fb27SDimitry Andric                                          nullptr));
1531349cc55cSDimitry Andric   }
15320b57cec5SDimitry Andric   if (addPass(&MachineBlockPlacementID)) {
15330b57cec5SDimitry Andric     // Run a separate pass to collect block placement statistics.
15340b57cec5SDimitry Andric     if (EnableBlockPlacementStats)
15350b57cec5SDimitry Andric       addPass(&MachineBlockPlacementStatsID);
15360b57cec5SDimitry Andric   }
15370b57cec5SDimitry Andric }
15380b57cec5SDimitry Andric 
15390b57cec5SDimitry Andric //===---------------------------------------------------------------------===//
15400b57cec5SDimitry Andric /// GlobalISel Configuration
15410b57cec5SDimitry Andric //===---------------------------------------------------------------------===//
15420b57cec5SDimitry Andric bool TargetPassConfig::isGlobalISelAbortEnabled() const {
15430b57cec5SDimitry Andric   return TM->Options.GlobalISelAbort == GlobalISelAbortMode::Enable;
15440b57cec5SDimitry Andric }
15450b57cec5SDimitry Andric 
15460b57cec5SDimitry Andric bool TargetPassConfig::reportDiagnosticWhenGlobalISelFallback() const {
15470b57cec5SDimitry Andric   return TM->Options.GlobalISelAbort == GlobalISelAbortMode::DisableWithDiag;
15480b57cec5SDimitry Andric }
15490b57cec5SDimitry Andric 
15500b57cec5SDimitry Andric bool TargetPassConfig::isGISelCSEEnabled() const {
15510b57cec5SDimitry Andric   return true;
15520b57cec5SDimitry Andric }
15530b57cec5SDimitry Andric 
15540b57cec5SDimitry Andric std::unique_ptr<CSEConfigBase> TargetPassConfig::getCSEConfig() const {
15558bcb0991SDimitry Andric   return std::make_unique<CSEConfigBase>();
15560b57cec5SDimitry Andric }
1557