106f32e7eSjoerg //===- TargetPassConfig.cpp - Target independent code generation passes ---===//
206f32e7eSjoerg //
306f32e7eSjoerg // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
406f32e7eSjoerg // See https://llvm.org/LICENSE.txt for license information.
506f32e7eSjoerg // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
606f32e7eSjoerg //
706f32e7eSjoerg //===----------------------------------------------------------------------===//
806f32e7eSjoerg //
906f32e7eSjoerg // This file defines interfaces to access the target independent code
1006f32e7eSjoerg // generation passes provided by the LLVM backend.
1106f32e7eSjoerg //
1206f32e7eSjoerg //===---------------------------------------------------------------------===//
1306f32e7eSjoerg 
1406f32e7eSjoerg #include "llvm/CodeGen/TargetPassConfig.h"
1506f32e7eSjoerg #include "llvm/ADT/DenseMap.h"
1606f32e7eSjoerg #include "llvm/ADT/SmallVector.h"
1706f32e7eSjoerg #include "llvm/ADT/StringRef.h"
1806f32e7eSjoerg #include "llvm/Analysis/BasicAliasAnalysis.h"
1906f32e7eSjoerg #include "llvm/Analysis/CFLAndersAliasAnalysis.h"
2006f32e7eSjoerg #include "llvm/Analysis/CFLSteensAliasAnalysis.h"
2106f32e7eSjoerg #include "llvm/Analysis/CallGraphSCCPass.h"
2206f32e7eSjoerg #include "llvm/Analysis/ScopedNoAliasAA.h"
2306f32e7eSjoerg #include "llvm/Analysis/TargetTransformInfo.h"
2406f32e7eSjoerg #include "llvm/Analysis/TypeBasedAliasAnalysis.h"
2506f32e7eSjoerg #include "llvm/CodeGen/CSEConfigBase.h"
2606f32e7eSjoerg #include "llvm/CodeGen/MachineFunctionPass.h"
2706f32e7eSjoerg #include "llvm/CodeGen/MachinePassRegistry.h"
2806f32e7eSjoerg #include "llvm/CodeGen/Passes.h"
2906f32e7eSjoerg #include "llvm/CodeGen/RegAllocRegistry.h"
3006f32e7eSjoerg #include "llvm/IR/IRPrintingPasses.h"
3106f32e7eSjoerg #include "llvm/IR/LegacyPassManager.h"
32*da58b97aSjoerg #include "llvm/IR/PassInstrumentation.h"
3306f32e7eSjoerg #include "llvm/IR/Verifier.h"
34*da58b97aSjoerg #include "llvm/InitializePasses.h"
3506f32e7eSjoerg #include "llvm/MC/MCAsmInfo.h"
3606f32e7eSjoerg #include "llvm/MC/MCTargetOptions.h"
3706f32e7eSjoerg #include "llvm/Pass.h"
3806f32e7eSjoerg #include "llvm/Support/CodeGen.h"
3906f32e7eSjoerg #include "llvm/Support/CommandLine.h"
4006f32e7eSjoerg #include "llvm/Support/Compiler.h"
4106f32e7eSjoerg #include "llvm/Support/Debug.h"
42*da58b97aSjoerg #include "llvm/Support/Discriminator.h"
4306f32e7eSjoerg #include "llvm/Support/ErrorHandling.h"
4406f32e7eSjoerg #include "llvm/Support/SaveAndRestore.h"
45*da58b97aSjoerg #include "llvm/Support/Threading.h"
46*da58b97aSjoerg #include "llvm/Target/CGPassBuilderOption.h"
4706f32e7eSjoerg #include "llvm/Target/TargetMachine.h"
4806f32e7eSjoerg #include "llvm/Transforms/Scalar.h"
4906f32e7eSjoerg #include "llvm/Transforms/Utils.h"
5006f32e7eSjoerg #include "llvm/Transforms/Utils/SymbolRewriter.h"
5106f32e7eSjoerg #include <cassert>
5206f32e7eSjoerg #include <string>
5306f32e7eSjoerg 
5406f32e7eSjoerg using namespace llvm;
5506f32e7eSjoerg 
5606f32e7eSjoerg static cl::opt<bool>
5706f32e7eSjoerg     EnableIPRA("enable-ipra", cl::init(false), cl::Hidden,
5806f32e7eSjoerg                cl::desc("Enable interprocedural register allocation "
5906f32e7eSjoerg                         "to reduce load/store at procedure calls."));
6006f32e7eSjoerg static cl::opt<bool> DisablePostRASched("disable-post-ra", cl::Hidden,
6106f32e7eSjoerg     cl::desc("Disable Post Regalloc Scheduler"));
6206f32e7eSjoerg static cl::opt<bool> DisableBranchFold("disable-branch-fold", cl::Hidden,
6306f32e7eSjoerg     cl::desc("Disable branch folding"));
6406f32e7eSjoerg static cl::opt<bool> DisableTailDuplicate("disable-tail-duplicate", cl::Hidden,
6506f32e7eSjoerg     cl::desc("Disable tail duplication"));
6606f32e7eSjoerg static cl::opt<bool> DisableEarlyTailDup("disable-early-taildup", cl::Hidden,
6706f32e7eSjoerg     cl::desc("Disable pre-register allocation tail duplication"));
6806f32e7eSjoerg static cl::opt<bool> DisableBlockPlacement("disable-block-placement",
6906f32e7eSjoerg     cl::Hidden, cl::desc("Disable probability-driven block placement"));
7006f32e7eSjoerg static cl::opt<bool> EnableBlockPlacementStats("enable-block-placement-stats",
7106f32e7eSjoerg     cl::Hidden, cl::desc("Collect probability-driven block placement stats"));
7206f32e7eSjoerg static cl::opt<bool> DisableSSC("disable-ssc", cl::Hidden,
7306f32e7eSjoerg     cl::desc("Disable Stack Slot Coloring"));
7406f32e7eSjoerg static cl::opt<bool> DisableMachineDCE("disable-machine-dce", cl::Hidden,
7506f32e7eSjoerg     cl::desc("Disable Machine Dead Code Elimination"));
7606f32e7eSjoerg static cl::opt<bool> DisableEarlyIfConversion("disable-early-ifcvt", cl::Hidden,
7706f32e7eSjoerg     cl::desc("Disable Early If-conversion"));
7806f32e7eSjoerg static cl::opt<bool> DisableMachineLICM("disable-machine-licm", cl::Hidden,
7906f32e7eSjoerg     cl::desc("Disable Machine LICM"));
8006f32e7eSjoerg static cl::opt<bool> DisableMachineCSE("disable-machine-cse", cl::Hidden,
8106f32e7eSjoerg     cl::desc("Disable Machine Common Subexpression Elimination"));
8206f32e7eSjoerg static cl::opt<cl::boolOrDefault> OptimizeRegAlloc(
8306f32e7eSjoerg     "optimize-regalloc", cl::Hidden,
8406f32e7eSjoerg     cl::desc("Enable optimized register allocation compilation path."));
8506f32e7eSjoerg static cl::opt<bool> DisablePostRAMachineLICM("disable-postra-machine-licm",
8606f32e7eSjoerg     cl::Hidden,
8706f32e7eSjoerg     cl::desc("Disable Machine LICM"));
8806f32e7eSjoerg static cl::opt<bool> DisableMachineSink("disable-machine-sink", cl::Hidden,
8906f32e7eSjoerg     cl::desc("Disable Machine Sinking"));
9006f32e7eSjoerg static cl::opt<bool> DisablePostRAMachineSink("disable-postra-machine-sink",
9106f32e7eSjoerg     cl::Hidden,
9206f32e7eSjoerg     cl::desc("Disable PostRA Machine Sinking"));
9306f32e7eSjoerg static cl::opt<bool> DisableLSR("disable-lsr", cl::Hidden,
9406f32e7eSjoerg     cl::desc("Disable Loop Strength Reduction Pass"));
9506f32e7eSjoerg static cl::opt<bool> DisableConstantHoisting("disable-constant-hoisting",
9606f32e7eSjoerg     cl::Hidden, cl::desc("Disable ConstantHoisting"));
9706f32e7eSjoerg static cl::opt<bool> DisableCGP("disable-cgp", cl::Hidden,
9806f32e7eSjoerg     cl::desc("Disable Codegen Prepare"));
9906f32e7eSjoerg static cl::opt<bool> DisableCopyProp("disable-copyprop", cl::Hidden,
10006f32e7eSjoerg     cl::desc("Disable Copy Propagation pass"));
10106f32e7eSjoerg static cl::opt<bool> DisablePartialLibcallInlining("disable-partial-libcall-inlining",
10206f32e7eSjoerg     cl::Hidden, cl::desc("Disable Partial Libcall Inlining"));
10306f32e7eSjoerg static cl::opt<bool> EnableImplicitNullChecks(
10406f32e7eSjoerg     "enable-implicit-null-checks",
10506f32e7eSjoerg     cl::desc("Fold null checks into faulting memory operations"),
10606f32e7eSjoerg     cl::init(false), cl::Hidden);
10706f32e7eSjoerg static cl::opt<bool> DisableMergeICmps("disable-mergeicmps",
10806f32e7eSjoerg     cl::desc("Disable MergeICmps Pass"),
10906f32e7eSjoerg     cl::init(false), cl::Hidden);
11006f32e7eSjoerg static cl::opt<bool> PrintLSR("print-lsr-output", cl::Hidden,
11106f32e7eSjoerg     cl::desc("Print LLVM IR produced by the loop-reduce pass"));
11206f32e7eSjoerg static cl::opt<bool> PrintISelInput("print-isel-input", cl::Hidden,
11306f32e7eSjoerg     cl::desc("Print LLVM IR input to isel pass"));
11406f32e7eSjoerg static cl::opt<bool> PrintGCInfo("print-gc", cl::Hidden,
11506f32e7eSjoerg     cl::desc("Dump garbage collector data"));
11606f32e7eSjoerg static cl::opt<cl::boolOrDefault>
11706f32e7eSjoerg     VerifyMachineCode("verify-machineinstrs", cl::Hidden,
11806f32e7eSjoerg                       cl::desc("Verify generated machine code"),
11906f32e7eSjoerg                       cl::ZeroOrMore);
120*da58b97aSjoerg static cl::opt<cl::boolOrDefault> DebugifyAndStripAll(
121*da58b97aSjoerg     "debugify-and-strip-all-safe", cl::Hidden,
122*da58b97aSjoerg     cl::desc(
123*da58b97aSjoerg         "Debugify MIR before and Strip debug after "
124*da58b97aSjoerg         "each pass except those known to be unsafe when debug info is present"),
125*da58b97aSjoerg     cl::ZeroOrMore);
126*da58b97aSjoerg static cl::opt<cl::boolOrDefault> DebugifyCheckAndStripAll(
127*da58b97aSjoerg     "debugify-check-and-strip-all-safe", cl::Hidden,
128*da58b97aSjoerg     cl::desc(
129*da58b97aSjoerg         "Debugify MIR before, by checking and stripping the debug info after, "
130*da58b97aSjoerg         "each pass except those known to be unsafe when debug info is present"),
131*da58b97aSjoerg     cl::ZeroOrMore);
13206f32e7eSjoerg // Enable or disable the MachineOutliner.
13306f32e7eSjoerg static cl::opt<RunOutliner> EnableMachineOutliner(
13406f32e7eSjoerg     "enable-machine-outliner", cl::desc("Enable the machine outliner"),
135*da58b97aSjoerg     cl::Hidden, cl::ValueOptional, cl::init(RunOutliner::TargetDefault),
136*da58b97aSjoerg     cl::values(clEnumValN(RunOutliner::AlwaysOutline, "always",
13706f32e7eSjoerg                           "Run on all functions guaranteed to be beneficial"),
138*da58b97aSjoerg                clEnumValN(RunOutliner::NeverOutline, "never",
139*da58b97aSjoerg                           "Disable all outlining"),
14006f32e7eSjoerg                // Sentinel value for unspecified option.
141*da58b97aSjoerg                clEnumValN(RunOutliner::AlwaysOutline, "", "")));
14206f32e7eSjoerg // Enable or disable FastISel. Both options are needed, because
14306f32e7eSjoerg // FastISel is enabled by default with -fast, and we wish to be
14406f32e7eSjoerg // able to enable or disable fast-isel independently from -O0.
14506f32e7eSjoerg static cl::opt<cl::boolOrDefault>
14606f32e7eSjoerg EnableFastISelOption("fast-isel", cl::Hidden,
14706f32e7eSjoerg   cl::desc("Enable the \"fast\" instruction selector"));
14806f32e7eSjoerg 
14906f32e7eSjoerg static cl::opt<cl::boolOrDefault> EnableGlobalISelOption(
15006f32e7eSjoerg     "global-isel", cl::Hidden,
15106f32e7eSjoerg     cl::desc("Enable the \"global\" instruction selector"));
15206f32e7eSjoerg 
153*da58b97aSjoerg // FIXME: remove this after switching to NPM or GlobalISel, whichever gets there
154*da58b97aSjoerg //        first...
155*da58b97aSjoerg static cl::opt<bool>
156*da58b97aSjoerg     PrintAfterISel("print-after-isel", cl::init(false), cl::Hidden,
157*da58b97aSjoerg                    cl::desc("Print machine instrs after ISel"));
15806f32e7eSjoerg 
15906f32e7eSjoerg static cl::opt<GlobalISelAbortMode> EnableGlobalISelAbort(
16006f32e7eSjoerg     "global-isel-abort", cl::Hidden,
16106f32e7eSjoerg     cl::desc("Enable abort calls when \"global\" instruction selection "
16206f32e7eSjoerg              "fails to lower/select an instruction"),
16306f32e7eSjoerg     cl::values(
16406f32e7eSjoerg         clEnumValN(GlobalISelAbortMode::Disable, "0", "Disable the abort"),
16506f32e7eSjoerg         clEnumValN(GlobalISelAbortMode::Enable, "1", "Enable the abort"),
16606f32e7eSjoerg         clEnumValN(GlobalISelAbortMode::DisableWithDiag, "2",
16706f32e7eSjoerg                    "Disable the abort but emit a diagnostic on failure")));
16806f32e7eSjoerg 
169*da58b97aSjoerg // An option that disables inserting FS-AFDO discriminators before emit.
170*da58b97aSjoerg // This is mainly for debugging and tuning purpose.
171*da58b97aSjoerg static cl::opt<bool>
172*da58b97aSjoerg     FSNoFinalDiscrim("fs-no-final-discrim", cl::init(false), cl::Hidden,
173*da58b97aSjoerg                      cl::desc("Do not insert FS-AFDO discriminators before "
174*da58b97aSjoerg                               "emit."));
175*da58b97aSjoerg 
17606f32e7eSjoerg // Temporary option to allow experimenting with MachineScheduler as a post-RA
17706f32e7eSjoerg // scheduler. Targets can "properly" enable this with
17806f32e7eSjoerg // substitutePass(&PostRASchedulerID, &PostMachineSchedulerID).
17906f32e7eSjoerg // Targets can return true in targetSchedulesPostRAScheduling() and
18006f32e7eSjoerg // insert a PostRA scheduling pass wherever it wants.
18106f32e7eSjoerg static cl::opt<bool> MISchedPostRA(
18206f32e7eSjoerg     "misched-postra", cl::Hidden,
18306f32e7eSjoerg     cl::desc(
18406f32e7eSjoerg         "Run MachineScheduler post regalloc (independent of preRA sched)"));
18506f32e7eSjoerg 
18606f32e7eSjoerg // Experimental option to run live interval analysis early.
18706f32e7eSjoerg static cl::opt<bool> EarlyLiveIntervals("early-live-intervals", cl::Hidden,
18806f32e7eSjoerg     cl::desc("Run live interval analysis earlier in the pipeline"));
18906f32e7eSjoerg 
19006f32e7eSjoerg // Experimental option to use CFL-AA in codegen
19106f32e7eSjoerg static cl::opt<CFLAAType> UseCFLAA(
19206f32e7eSjoerg     "use-cfl-aa-in-codegen", cl::init(CFLAAType::None), cl::Hidden,
19306f32e7eSjoerg     cl::desc("Enable the new, experimental CFL alias analysis in CodeGen"),
19406f32e7eSjoerg     cl::values(clEnumValN(CFLAAType::None, "none", "Disable CFL-AA"),
19506f32e7eSjoerg                clEnumValN(CFLAAType::Steensgaard, "steens",
19606f32e7eSjoerg                           "Enable unification-based CFL-AA"),
19706f32e7eSjoerg                clEnumValN(CFLAAType::Andersen, "anders",
19806f32e7eSjoerg                           "Enable inclusion-based CFL-AA"),
19906f32e7eSjoerg                clEnumValN(CFLAAType::Both, "both",
20006f32e7eSjoerg                           "Enable both variants of CFL-AA")));
20106f32e7eSjoerg 
20206f32e7eSjoerg /// Option names for limiting the codegen pipeline.
20306f32e7eSjoerg /// Those are used in error reporting and we didn't want
20406f32e7eSjoerg /// to duplicate their names all over the place.
205*da58b97aSjoerg static const char StartAfterOptName[] = "start-after";
206*da58b97aSjoerg static const char StartBeforeOptName[] = "start-before";
207*da58b97aSjoerg static const char StopAfterOptName[] = "stop-after";
208*da58b97aSjoerg static const char StopBeforeOptName[] = "stop-before";
20906f32e7eSjoerg 
21006f32e7eSjoerg static cl::opt<std::string>
21106f32e7eSjoerg     StartAfterOpt(StringRef(StartAfterOptName),
21206f32e7eSjoerg                   cl::desc("Resume compilation after a specific pass"),
21306f32e7eSjoerg                   cl::value_desc("pass-name"), cl::init(""), cl::Hidden);
21406f32e7eSjoerg 
21506f32e7eSjoerg static cl::opt<std::string>
21606f32e7eSjoerg     StartBeforeOpt(StringRef(StartBeforeOptName),
21706f32e7eSjoerg                    cl::desc("Resume compilation before a specific pass"),
21806f32e7eSjoerg                    cl::value_desc("pass-name"), cl::init(""), cl::Hidden);
21906f32e7eSjoerg 
22006f32e7eSjoerg static cl::opt<std::string>
22106f32e7eSjoerg     StopAfterOpt(StringRef(StopAfterOptName),
22206f32e7eSjoerg                  cl::desc("Stop compilation after a specific pass"),
22306f32e7eSjoerg                  cl::value_desc("pass-name"), cl::init(""), cl::Hidden);
22406f32e7eSjoerg 
22506f32e7eSjoerg static cl::opt<std::string>
22606f32e7eSjoerg     StopBeforeOpt(StringRef(StopBeforeOptName),
22706f32e7eSjoerg                   cl::desc("Stop compilation before a specific pass"),
22806f32e7eSjoerg                   cl::value_desc("pass-name"), cl::init(""), cl::Hidden);
22906f32e7eSjoerg 
230*da58b97aSjoerg /// Enable the machine function splitter pass.
231*da58b97aSjoerg static cl::opt<bool> EnableMachineFunctionSplitter(
232*da58b97aSjoerg     "enable-split-machine-functions", cl::Hidden,
233*da58b97aSjoerg     cl::desc("Split out cold blocks from machine functions based on profile "
234*da58b97aSjoerg              "information."));
235*da58b97aSjoerg 
236*da58b97aSjoerg /// Disable the expand reductions pass for testing.
237*da58b97aSjoerg static cl::opt<bool> DisableExpandReductions(
238*da58b97aSjoerg     "disable-expand-reductions", cl::init(false), cl::Hidden,
239*da58b97aSjoerg     cl::desc("Disable the expand reduction intrinsics pass from running"));
240*da58b97aSjoerg 
24106f32e7eSjoerg /// Allow standard passes to be disabled by command line options. This supports
24206f32e7eSjoerg /// simple binary flags that either suppress the pass or do nothing.
24306f32e7eSjoerg /// i.e. -disable-mypass=false has no effect.
24406f32e7eSjoerg /// These should be converted to boolOrDefault in order to use applyOverride.
applyDisable(IdentifyingPassPtr PassID,bool Override)24506f32e7eSjoerg static IdentifyingPassPtr applyDisable(IdentifyingPassPtr PassID,
24606f32e7eSjoerg                                        bool Override) {
24706f32e7eSjoerg   if (Override)
24806f32e7eSjoerg     return IdentifyingPassPtr();
24906f32e7eSjoerg   return PassID;
25006f32e7eSjoerg }
25106f32e7eSjoerg 
25206f32e7eSjoerg /// Allow standard passes to be disabled by the command line, regardless of who
25306f32e7eSjoerg /// is adding the pass.
25406f32e7eSjoerg ///
25506f32e7eSjoerg /// StandardID is the pass identified in the standard pass pipeline and provided
25606f32e7eSjoerg /// to addPass(). It may be a target-specific ID in the case that the target
25706f32e7eSjoerg /// directly adds its own pass, but in that case we harmlessly fall through.
25806f32e7eSjoerg ///
25906f32e7eSjoerg /// TargetID is the pass that the target has configured to override StandardID.
26006f32e7eSjoerg ///
26106f32e7eSjoerg /// StandardID may be a pseudo ID. In that case TargetID is the name of the real
26206f32e7eSjoerg /// pass to run. This allows multiple options to control a single pass depending
26306f32e7eSjoerg /// on where in the pipeline that pass is added.
overridePass(AnalysisID StandardID,IdentifyingPassPtr TargetID)26406f32e7eSjoerg static IdentifyingPassPtr overridePass(AnalysisID StandardID,
26506f32e7eSjoerg                                        IdentifyingPassPtr TargetID) {
26606f32e7eSjoerg   if (StandardID == &PostRASchedulerID)
26706f32e7eSjoerg     return applyDisable(TargetID, DisablePostRASched);
26806f32e7eSjoerg 
26906f32e7eSjoerg   if (StandardID == &BranchFolderPassID)
27006f32e7eSjoerg     return applyDisable(TargetID, DisableBranchFold);
27106f32e7eSjoerg 
27206f32e7eSjoerg   if (StandardID == &TailDuplicateID)
27306f32e7eSjoerg     return applyDisable(TargetID, DisableTailDuplicate);
27406f32e7eSjoerg 
27506f32e7eSjoerg   if (StandardID == &EarlyTailDuplicateID)
27606f32e7eSjoerg     return applyDisable(TargetID, DisableEarlyTailDup);
27706f32e7eSjoerg 
27806f32e7eSjoerg   if (StandardID == &MachineBlockPlacementID)
27906f32e7eSjoerg     return applyDisable(TargetID, DisableBlockPlacement);
28006f32e7eSjoerg 
28106f32e7eSjoerg   if (StandardID == &StackSlotColoringID)
28206f32e7eSjoerg     return applyDisable(TargetID, DisableSSC);
28306f32e7eSjoerg 
28406f32e7eSjoerg   if (StandardID == &DeadMachineInstructionElimID)
28506f32e7eSjoerg     return applyDisable(TargetID, DisableMachineDCE);
28606f32e7eSjoerg 
28706f32e7eSjoerg   if (StandardID == &EarlyIfConverterID)
28806f32e7eSjoerg     return applyDisable(TargetID, DisableEarlyIfConversion);
28906f32e7eSjoerg 
29006f32e7eSjoerg   if (StandardID == &EarlyMachineLICMID)
29106f32e7eSjoerg     return applyDisable(TargetID, DisableMachineLICM);
29206f32e7eSjoerg 
29306f32e7eSjoerg   if (StandardID == &MachineCSEID)
29406f32e7eSjoerg     return applyDisable(TargetID, DisableMachineCSE);
29506f32e7eSjoerg 
29606f32e7eSjoerg   if (StandardID == &MachineLICMID)
29706f32e7eSjoerg     return applyDisable(TargetID, DisablePostRAMachineLICM);
29806f32e7eSjoerg 
29906f32e7eSjoerg   if (StandardID == &MachineSinkingID)
30006f32e7eSjoerg     return applyDisable(TargetID, DisableMachineSink);
30106f32e7eSjoerg 
30206f32e7eSjoerg   if (StandardID == &PostRAMachineSinkingID)
30306f32e7eSjoerg     return applyDisable(TargetID, DisablePostRAMachineSink);
30406f32e7eSjoerg 
30506f32e7eSjoerg   if (StandardID == &MachineCopyPropagationID)
30606f32e7eSjoerg     return applyDisable(TargetID, DisableCopyProp);
30706f32e7eSjoerg 
30806f32e7eSjoerg   return TargetID;
30906f32e7eSjoerg }
31006f32e7eSjoerg 
31106f32e7eSjoerg //===---------------------------------------------------------------------===//
31206f32e7eSjoerg /// TargetPassConfig
31306f32e7eSjoerg //===---------------------------------------------------------------------===//
31406f32e7eSjoerg 
31506f32e7eSjoerg INITIALIZE_PASS(TargetPassConfig, "targetpassconfig",
31606f32e7eSjoerg                 "Target Pass Configuration", false, false)
31706f32e7eSjoerg char TargetPassConfig::ID = 0;
31806f32e7eSjoerg 
31906f32e7eSjoerg namespace {
32006f32e7eSjoerg 
32106f32e7eSjoerg struct InsertedPass {
32206f32e7eSjoerg   AnalysisID TargetPassID;
32306f32e7eSjoerg   IdentifyingPassPtr InsertedPassID;
32406f32e7eSjoerg   bool VerifyAfter;
32506f32e7eSjoerg 
InsertedPass__anon947fd5690111::InsertedPass32606f32e7eSjoerg   InsertedPass(AnalysisID TargetPassID, IdentifyingPassPtr InsertedPassID,
327*da58b97aSjoerg                bool VerifyAfter)
32806f32e7eSjoerg       : TargetPassID(TargetPassID), InsertedPassID(InsertedPassID),
329*da58b97aSjoerg         VerifyAfter(VerifyAfter) {}
33006f32e7eSjoerg 
getInsertedPass__anon947fd5690111::InsertedPass33106f32e7eSjoerg   Pass *getInsertedPass() const {
33206f32e7eSjoerg     assert(InsertedPassID.isValid() && "Illegal Pass ID!");
33306f32e7eSjoerg     if (InsertedPassID.isInstance())
33406f32e7eSjoerg       return InsertedPassID.getInstance();
33506f32e7eSjoerg     Pass *NP = Pass::createPass(InsertedPassID.getID());
33606f32e7eSjoerg     assert(NP && "Pass ID not registered");
33706f32e7eSjoerg     return NP;
33806f32e7eSjoerg   }
33906f32e7eSjoerg };
34006f32e7eSjoerg 
34106f32e7eSjoerg } // end anonymous namespace
34206f32e7eSjoerg 
34306f32e7eSjoerg namespace llvm {
34406f32e7eSjoerg 
345*da58b97aSjoerg extern cl::opt<bool> EnableFSDiscriminator;
346*da58b97aSjoerg 
34706f32e7eSjoerg class PassConfigImpl {
34806f32e7eSjoerg public:
34906f32e7eSjoerg   // List of passes explicitly substituted by this target. Normally this is
35006f32e7eSjoerg   // empty, but it is a convenient way to suppress or replace specific passes
35106f32e7eSjoerg   // that are part of a standard pass pipeline without overridding the entire
35206f32e7eSjoerg   // pipeline. This mechanism allows target options to inherit a standard pass's
35306f32e7eSjoerg   // user interface. For example, a target may disable a standard pass by
35406f32e7eSjoerg   // default by substituting a pass ID of zero, and the user may still enable
35506f32e7eSjoerg   // that standard pass with an explicit command line option.
35606f32e7eSjoerg   DenseMap<AnalysisID,IdentifyingPassPtr> TargetPasses;
35706f32e7eSjoerg 
35806f32e7eSjoerg   /// Store the pairs of <AnalysisID, AnalysisID> of which the second pass
35906f32e7eSjoerg   /// is inserted after each instance of the first one.
36006f32e7eSjoerg   SmallVector<InsertedPass, 4> InsertedPasses;
36106f32e7eSjoerg };
36206f32e7eSjoerg 
36306f32e7eSjoerg } // end namespace llvm
36406f32e7eSjoerg 
36506f32e7eSjoerg // Out of line virtual method.
~TargetPassConfig()36606f32e7eSjoerg TargetPassConfig::~TargetPassConfig() {
36706f32e7eSjoerg   delete Impl;
36806f32e7eSjoerg }
36906f32e7eSjoerg 
getPassInfo(StringRef PassName)37006f32e7eSjoerg static const PassInfo *getPassInfo(StringRef PassName) {
37106f32e7eSjoerg   if (PassName.empty())
37206f32e7eSjoerg     return nullptr;
37306f32e7eSjoerg 
37406f32e7eSjoerg   const PassRegistry &PR = *PassRegistry::getPassRegistry();
37506f32e7eSjoerg   const PassInfo *PI = PR.getPassInfo(PassName);
37606f32e7eSjoerg   if (!PI)
37706f32e7eSjoerg     report_fatal_error(Twine('\"') + Twine(PassName) +
37806f32e7eSjoerg                        Twine("\" pass is not registered."));
37906f32e7eSjoerg   return PI;
38006f32e7eSjoerg }
38106f32e7eSjoerg 
getPassIDFromName(StringRef PassName)38206f32e7eSjoerg static AnalysisID getPassIDFromName(StringRef PassName) {
38306f32e7eSjoerg   const PassInfo *PI = getPassInfo(PassName);
38406f32e7eSjoerg   return PI ? PI->getTypeInfo() : nullptr;
38506f32e7eSjoerg }
38606f32e7eSjoerg 
38706f32e7eSjoerg static std::pair<StringRef, unsigned>
getPassNameAndInstanceNum(StringRef PassName)38806f32e7eSjoerg getPassNameAndInstanceNum(StringRef PassName) {
38906f32e7eSjoerg   StringRef Name, InstanceNumStr;
39006f32e7eSjoerg   std::tie(Name, InstanceNumStr) = PassName.split(',');
39106f32e7eSjoerg 
39206f32e7eSjoerg   unsigned InstanceNum = 0;
39306f32e7eSjoerg   if (!InstanceNumStr.empty() && InstanceNumStr.getAsInteger(10, InstanceNum))
39406f32e7eSjoerg     report_fatal_error("invalid pass instance specifier " + PassName);
39506f32e7eSjoerg 
39606f32e7eSjoerg   return std::make_pair(Name, InstanceNum);
39706f32e7eSjoerg }
39806f32e7eSjoerg 
setStartStopPasses()39906f32e7eSjoerg void TargetPassConfig::setStartStopPasses() {
40006f32e7eSjoerg   StringRef StartBeforeName;
40106f32e7eSjoerg   std::tie(StartBeforeName, StartBeforeInstanceNum) =
40206f32e7eSjoerg     getPassNameAndInstanceNum(StartBeforeOpt);
40306f32e7eSjoerg 
40406f32e7eSjoerg   StringRef StartAfterName;
40506f32e7eSjoerg   std::tie(StartAfterName, StartAfterInstanceNum) =
40606f32e7eSjoerg     getPassNameAndInstanceNum(StartAfterOpt);
40706f32e7eSjoerg 
40806f32e7eSjoerg   StringRef StopBeforeName;
40906f32e7eSjoerg   std::tie(StopBeforeName, StopBeforeInstanceNum)
41006f32e7eSjoerg     = getPassNameAndInstanceNum(StopBeforeOpt);
41106f32e7eSjoerg 
41206f32e7eSjoerg   StringRef StopAfterName;
41306f32e7eSjoerg   std::tie(StopAfterName, StopAfterInstanceNum)
41406f32e7eSjoerg     = getPassNameAndInstanceNum(StopAfterOpt);
41506f32e7eSjoerg 
41606f32e7eSjoerg   StartBefore = getPassIDFromName(StartBeforeName);
41706f32e7eSjoerg   StartAfter = getPassIDFromName(StartAfterName);
41806f32e7eSjoerg   StopBefore = getPassIDFromName(StopBeforeName);
41906f32e7eSjoerg   StopAfter = getPassIDFromName(StopAfterName);
42006f32e7eSjoerg   if (StartBefore && StartAfter)
42106f32e7eSjoerg     report_fatal_error(Twine(StartBeforeOptName) + Twine(" and ") +
42206f32e7eSjoerg                        Twine(StartAfterOptName) + Twine(" specified!"));
42306f32e7eSjoerg   if (StopBefore && StopAfter)
42406f32e7eSjoerg     report_fatal_error(Twine(StopBeforeOptName) + Twine(" and ") +
42506f32e7eSjoerg                        Twine(StopAfterOptName) + Twine(" specified!"));
42606f32e7eSjoerg   Started = (StartAfter == nullptr) && (StartBefore == nullptr);
42706f32e7eSjoerg }
42806f32e7eSjoerg 
getCGPassBuilderOption()429*da58b97aSjoerg CGPassBuilderOption llvm::getCGPassBuilderOption() {
430*da58b97aSjoerg   CGPassBuilderOption Opt;
431*da58b97aSjoerg 
432*da58b97aSjoerg #define SET_OPTION(Option)                                                     \
433*da58b97aSjoerg   if (Option.getNumOccurrences())                                              \
434*da58b97aSjoerg     Opt.Option = Option;
435*da58b97aSjoerg 
436*da58b97aSjoerg   SET_OPTION(EnableFastISelOption)
437*da58b97aSjoerg   SET_OPTION(EnableGlobalISelAbort)
438*da58b97aSjoerg   SET_OPTION(EnableGlobalISelOption)
439*da58b97aSjoerg   SET_OPTION(EnableIPRA)
440*da58b97aSjoerg   SET_OPTION(OptimizeRegAlloc)
441*da58b97aSjoerg   SET_OPTION(VerifyMachineCode)
442*da58b97aSjoerg 
443*da58b97aSjoerg #define SET_BOOLEAN_OPTION(Option) Opt.Option = Option;
444*da58b97aSjoerg 
445*da58b97aSjoerg   SET_BOOLEAN_OPTION(EarlyLiveIntervals)
446*da58b97aSjoerg   SET_BOOLEAN_OPTION(EnableBlockPlacementStats)
447*da58b97aSjoerg   SET_BOOLEAN_OPTION(EnableImplicitNullChecks)
448*da58b97aSjoerg   SET_BOOLEAN_OPTION(EnableMachineOutliner)
449*da58b97aSjoerg   SET_BOOLEAN_OPTION(MISchedPostRA)
450*da58b97aSjoerg   SET_BOOLEAN_OPTION(UseCFLAA)
451*da58b97aSjoerg   SET_BOOLEAN_OPTION(DisableMergeICmps)
452*da58b97aSjoerg   SET_BOOLEAN_OPTION(DisableLSR)
453*da58b97aSjoerg   SET_BOOLEAN_OPTION(DisableConstantHoisting)
454*da58b97aSjoerg   SET_BOOLEAN_OPTION(DisableCGP)
455*da58b97aSjoerg   SET_BOOLEAN_OPTION(DisablePartialLibcallInlining)
456*da58b97aSjoerg   SET_BOOLEAN_OPTION(PrintLSR)
457*da58b97aSjoerg   SET_BOOLEAN_OPTION(PrintISelInput)
458*da58b97aSjoerg   SET_BOOLEAN_OPTION(PrintGCInfo)
459*da58b97aSjoerg 
460*da58b97aSjoerg   return Opt;
461*da58b97aSjoerg }
462*da58b97aSjoerg 
registerPartialPipelineCallback(PassInstrumentationCallbacks & PIC,LLVMTargetMachine & LLVMTM)463*da58b97aSjoerg static void registerPartialPipelineCallback(PassInstrumentationCallbacks &PIC,
464*da58b97aSjoerg                                             LLVMTargetMachine &LLVMTM) {
465*da58b97aSjoerg   StringRef StartBefore;
466*da58b97aSjoerg   StringRef StartAfter;
467*da58b97aSjoerg   StringRef StopBefore;
468*da58b97aSjoerg   StringRef StopAfter;
469*da58b97aSjoerg 
470*da58b97aSjoerg   unsigned StartBeforeInstanceNum = 0;
471*da58b97aSjoerg   unsigned StartAfterInstanceNum = 0;
472*da58b97aSjoerg   unsigned StopBeforeInstanceNum = 0;
473*da58b97aSjoerg   unsigned StopAfterInstanceNum = 0;
474*da58b97aSjoerg 
475*da58b97aSjoerg   std::tie(StartBefore, StartBeforeInstanceNum) =
476*da58b97aSjoerg       getPassNameAndInstanceNum(StartBeforeOpt);
477*da58b97aSjoerg   std::tie(StartAfter, StartAfterInstanceNum) =
478*da58b97aSjoerg       getPassNameAndInstanceNum(StartAfterOpt);
479*da58b97aSjoerg   std::tie(StopBefore, StopBeforeInstanceNum) =
480*da58b97aSjoerg       getPassNameAndInstanceNum(StopBeforeOpt);
481*da58b97aSjoerg   std::tie(StopAfter, StopAfterInstanceNum) =
482*da58b97aSjoerg       getPassNameAndInstanceNum(StopAfterOpt);
483*da58b97aSjoerg 
484*da58b97aSjoerg   if (StartBefore.empty() && StartAfter.empty() && StopBefore.empty() &&
485*da58b97aSjoerg       StopAfter.empty())
486*da58b97aSjoerg     return;
487*da58b97aSjoerg 
488*da58b97aSjoerg   std::tie(StartBefore, std::ignore) =
489*da58b97aSjoerg       LLVMTM.getPassNameFromLegacyName(StartBefore);
490*da58b97aSjoerg   std::tie(StartAfter, std::ignore) =
491*da58b97aSjoerg       LLVMTM.getPassNameFromLegacyName(StartAfter);
492*da58b97aSjoerg   std::tie(StopBefore, std::ignore) =
493*da58b97aSjoerg       LLVMTM.getPassNameFromLegacyName(StopBefore);
494*da58b97aSjoerg   std::tie(StopAfter, std::ignore) =
495*da58b97aSjoerg       LLVMTM.getPassNameFromLegacyName(StopAfter);
496*da58b97aSjoerg   if (!StartBefore.empty() && !StartAfter.empty())
497*da58b97aSjoerg     report_fatal_error(Twine(StartBeforeOptName) + Twine(" and ") +
498*da58b97aSjoerg                        Twine(StartAfterOptName) + Twine(" specified!"));
499*da58b97aSjoerg   if (!StopBefore.empty() && !StopAfter.empty())
500*da58b97aSjoerg     report_fatal_error(Twine(StopBeforeOptName) + Twine(" and ") +
501*da58b97aSjoerg                        Twine(StopAfterOptName) + Twine(" specified!"));
502*da58b97aSjoerg 
503*da58b97aSjoerg   PIC.registerShouldRunOptionalPassCallback(
504*da58b97aSjoerg       [=, EnableCurrent = StartBefore.empty() && StartAfter.empty(),
505*da58b97aSjoerg        EnableNext = Optional<bool>(), StartBeforeCount = 0u,
506*da58b97aSjoerg        StartAfterCount = 0u, StopBeforeCount = 0u,
507*da58b97aSjoerg        StopAfterCount = 0u](StringRef P, Any) mutable {
508*da58b97aSjoerg         bool StartBeforePass = !StartBefore.empty() && P.contains(StartBefore);
509*da58b97aSjoerg         bool StartAfterPass = !StartAfter.empty() && P.contains(StartAfter);
510*da58b97aSjoerg         bool StopBeforePass = !StopBefore.empty() && P.contains(StopBefore);
511*da58b97aSjoerg         bool StopAfterPass = !StopAfter.empty() && P.contains(StopAfter);
512*da58b97aSjoerg 
513*da58b97aSjoerg         // Implement -start-after/-stop-after
514*da58b97aSjoerg         if (EnableNext) {
515*da58b97aSjoerg           EnableCurrent = *EnableNext;
516*da58b97aSjoerg           EnableNext.reset();
517*da58b97aSjoerg         }
518*da58b97aSjoerg 
519*da58b97aSjoerg         // Using PIC.registerAfterPassCallback won't work because if this
520*da58b97aSjoerg         // callback returns false, AfterPassCallback is also skipped.
521*da58b97aSjoerg         if (StartAfterPass && StartAfterCount++ == StartAfterInstanceNum) {
522*da58b97aSjoerg           assert(!EnableNext && "Error: assign to EnableNext more than once");
523*da58b97aSjoerg           EnableNext = true;
524*da58b97aSjoerg         }
525*da58b97aSjoerg         if (StopAfterPass && StopAfterCount++ == StopAfterInstanceNum) {
526*da58b97aSjoerg           assert(!EnableNext && "Error: assign to EnableNext more than once");
527*da58b97aSjoerg           EnableNext = false;
528*da58b97aSjoerg         }
529*da58b97aSjoerg 
530*da58b97aSjoerg         if (StartBeforePass && StartBeforeCount++ == StartBeforeInstanceNum)
531*da58b97aSjoerg           EnableCurrent = true;
532*da58b97aSjoerg         if (StopBeforePass && StopBeforeCount++ == StopBeforeInstanceNum)
533*da58b97aSjoerg           EnableCurrent = false;
534*da58b97aSjoerg         return EnableCurrent;
535*da58b97aSjoerg       });
536*da58b97aSjoerg }
537*da58b97aSjoerg 
registerCodeGenCallback(PassInstrumentationCallbacks & PIC,LLVMTargetMachine & LLVMTM)538*da58b97aSjoerg void llvm::registerCodeGenCallback(PassInstrumentationCallbacks &PIC,
539*da58b97aSjoerg                                    LLVMTargetMachine &LLVMTM) {
540*da58b97aSjoerg 
541*da58b97aSjoerg   // Register a callback for disabling passes.
542*da58b97aSjoerg   PIC.registerShouldRunOptionalPassCallback([](StringRef P, Any) {
543*da58b97aSjoerg 
544*da58b97aSjoerg #define DISABLE_PASS(Option, Name)                                             \
545*da58b97aSjoerg   if (Option && P.contains(#Name))                                             \
546*da58b97aSjoerg     return false;
547*da58b97aSjoerg     DISABLE_PASS(DisableBlockPlacement, MachineBlockPlacementPass)
548*da58b97aSjoerg     DISABLE_PASS(DisableBranchFold, BranchFolderPass)
549*da58b97aSjoerg     DISABLE_PASS(DisableCopyProp, MachineCopyPropagationPass)
550*da58b97aSjoerg     DISABLE_PASS(DisableEarlyIfConversion, EarlyIfConverterPass)
551*da58b97aSjoerg     DISABLE_PASS(DisableEarlyTailDup, EarlyTailDuplicatePass)
552*da58b97aSjoerg     DISABLE_PASS(DisableMachineCSE, MachineCSEPass)
553*da58b97aSjoerg     DISABLE_PASS(DisableMachineDCE, DeadMachineInstructionElimPass)
554*da58b97aSjoerg     DISABLE_PASS(DisableMachineLICM, EarlyMachineLICMPass)
555*da58b97aSjoerg     DISABLE_PASS(DisableMachineSink, MachineSinkingPass)
556*da58b97aSjoerg     DISABLE_PASS(DisablePostRAMachineLICM, MachineLICMPass)
557*da58b97aSjoerg     DISABLE_PASS(DisablePostRAMachineSink, PostRAMachineSinkingPass)
558*da58b97aSjoerg     DISABLE_PASS(DisablePostRASched, PostRASchedulerPass)
559*da58b97aSjoerg     DISABLE_PASS(DisableSSC, StackSlotColoringPass)
560*da58b97aSjoerg     DISABLE_PASS(DisableTailDuplicate, TailDuplicatePass)
561*da58b97aSjoerg 
562*da58b97aSjoerg     return true;
563*da58b97aSjoerg   });
564*da58b97aSjoerg 
565*da58b97aSjoerg   registerPartialPipelineCallback(PIC, LLVMTM);
566*da58b97aSjoerg }
567*da58b97aSjoerg 
56806f32e7eSjoerg // Out of line constructor provides default values for pass options and
56906f32e7eSjoerg // registers all common codegen passes.
TargetPassConfig(LLVMTargetMachine & TM,PassManagerBase & pm)57006f32e7eSjoerg TargetPassConfig::TargetPassConfig(LLVMTargetMachine &TM, PassManagerBase &pm)
57106f32e7eSjoerg     : ImmutablePass(ID), PM(&pm), TM(&TM) {
57206f32e7eSjoerg   Impl = new PassConfigImpl();
57306f32e7eSjoerg 
57406f32e7eSjoerg   // Register all target independent codegen passes to activate their PassIDs,
57506f32e7eSjoerg   // including this pass itself.
57606f32e7eSjoerg   initializeCodeGen(*PassRegistry::getPassRegistry());
57706f32e7eSjoerg 
57806f32e7eSjoerg   // Also register alias analysis passes required by codegen passes.
57906f32e7eSjoerg   initializeBasicAAWrapperPassPass(*PassRegistry::getPassRegistry());
58006f32e7eSjoerg   initializeAAResultsWrapperPassPass(*PassRegistry::getPassRegistry());
58106f32e7eSjoerg 
58206f32e7eSjoerg   if (EnableIPRA.getNumOccurrences())
58306f32e7eSjoerg     TM.Options.EnableIPRA = EnableIPRA;
58406f32e7eSjoerg   else {
58506f32e7eSjoerg     // If not explicitly specified, use target default.
58606f32e7eSjoerg     TM.Options.EnableIPRA |= TM.useIPRA();
58706f32e7eSjoerg   }
58806f32e7eSjoerg 
58906f32e7eSjoerg   if (TM.Options.EnableIPRA)
59006f32e7eSjoerg     setRequiresCodeGenSCCOrder();
59106f32e7eSjoerg 
59206f32e7eSjoerg   if (EnableGlobalISelAbort.getNumOccurrences())
59306f32e7eSjoerg     TM.Options.GlobalISelAbort = EnableGlobalISelAbort;
59406f32e7eSjoerg 
59506f32e7eSjoerg   setStartStopPasses();
59606f32e7eSjoerg }
59706f32e7eSjoerg 
getOptLevel() const59806f32e7eSjoerg CodeGenOpt::Level TargetPassConfig::getOptLevel() const {
59906f32e7eSjoerg   return TM->getOptLevel();
60006f32e7eSjoerg }
60106f32e7eSjoerg 
60206f32e7eSjoerg /// Insert InsertedPassID pass after TargetPassID.
insertPass(AnalysisID TargetPassID,IdentifyingPassPtr InsertedPassID,bool VerifyAfter)60306f32e7eSjoerg void TargetPassConfig::insertPass(AnalysisID TargetPassID,
60406f32e7eSjoerg                                   IdentifyingPassPtr InsertedPassID,
605*da58b97aSjoerg                                   bool VerifyAfter) {
60606f32e7eSjoerg   assert(((!InsertedPassID.isInstance() &&
60706f32e7eSjoerg            TargetPassID != InsertedPassID.getID()) ||
60806f32e7eSjoerg           (InsertedPassID.isInstance() &&
60906f32e7eSjoerg            TargetPassID != InsertedPassID.getInstance()->getPassID())) &&
61006f32e7eSjoerg          "Insert a pass after itself!");
611*da58b97aSjoerg   Impl->InsertedPasses.emplace_back(TargetPassID, InsertedPassID, VerifyAfter);
61206f32e7eSjoerg }
61306f32e7eSjoerg 
61406f32e7eSjoerg /// createPassConfig - Create a pass configuration object to be used by
61506f32e7eSjoerg /// addPassToEmitX methods for generating a pipeline of CodeGen passes.
61606f32e7eSjoerg ///
61706f32e7eSjoerg /// Targets may override this to extend TargetPassConfig.
createPassConfig(PassManagerBase & PM)61806f32e7eSjoerg TargetPassConfig *LLVMTargetMachine::createPassConfig(PassManagerBase &PM) {
61906f32e7eSjoerg   return new TargetPassConfig(*this, PM);
62006f32e7eSjoerg }
62106f32e7eSjoerg 
TargetPassConfig()62206f32e7eSjoerg TargetPassConfig::TargetPassConfig()
62306f32e7eSjoerg   : ImmutablePass(ID) {
62406f32e7eSjoerg   report_fatal_error("Trying to construct TargetPassConfig without a target "
62506f32e7eSjoerg                      "machine. Scheduling a CodeGen pass without a target "
62606f32e7eSjoerg                      "triple set?");
62706f32e7eSjoerg }
62806f32e7eSjoerg 
willCompleteCodeGenPipeline()62906f32e7eSjoerg bool TargetPassConfig::willCompleteCodeGenPipeline() {
63006f32e7eSjoerg   return StopBeforeOpt.empty() && StopAfterOpt.empty();
63106f32e7eSjoerg }
63206f32e7eSjoerg 
hasLimitedCodeGenPipeline()63306f32e7eSjoerg bool TargetPassConfig::hasLimitedCodeGenPipeline() {
63406f32e7eSjoerg   return !StartBeforeOpt.empty() || !StartAfterOpt.empty() ||
63506f32e7eSjoerg          !willCompleteCodeGenPipeline();
63606f32e7eSjoerg }
63706f32e7eSjoerg 
63806f32e7eSjoerg std::string
getLimitedCodeGenPipelineReason(const char * Separator)639*da58b97aSjoerg TargetPassConfig::getLimitedCodeGenPipelineReason(const char *Separator) {
64006f32e7eSjoerg   if (!hasLimitedCodeGenPipeline())
64106f32e7eSjoerg     return std::string();
64206f32e7eSjoerg   std::string Res;
64306f32e7eSjoerg   static cl::opt<std::string> *PassNames[] = {&StartAfterOpt, &StartBeforeOpt,
64406f32e7eSjoerg                                               &StopAfterOpt, &StopBeforeOpt};
64506f32e7eSjoerg   static const char *OptNames[] = {StartAfterOptName, StartBeforeOptName,
64606f32e7eSjoerg                                    StopAfterOptName, StopBeforeOptName};
64706f32e7eSjoerg   bool IsFirst = true;
64806f32e7eSjoerg   for (int Idx = 0; Idx < 4; ++Idx)
64906f32e7eSjoerg     if (!PassNames[Idx]->empty()) {
65006f32e7eSjoerg       if (!IsFirst)
65106f32e7eSjoerg         Res += Separator;
65206f32e7eSjoerg       IsFirst = false;
65306f32e7eSjoerg       Res += OptNames[Idx];
65406f32e7eSjoerg     }
65506f32e7eSjoerg   return Res;
65606f32e7eSjoerg }
65706f32e7eSjoerg 
65806f32e7eSjoerg // Helper to verify the analysis is really immutable.
setOpt(bool & Opt,bool Val)65906f32e7eSjoerg void TargetPassConfig::setOpt(bool &Opt, bool Val) {
66006f32e7eSjoerg   assert(!Initialized && "PassConfig is immutable");
66106f32e7eSjoerg   Opt = Val;
66206f32e7eSjoerg }
66306f32e7eSjoerg 
substitutePass(AnalysisID StandardID,IdentifyingPassPtr TargetID)66406f32e7eSjoerg void TargetPassConfig::substitutePass(AnalysisID StandardID,
66506f32e7eSjoerg                                       IdentifyingPassPtr TargetID) {
66606f32e7eSjoerg   Impl->TargetPasses[StandardID] = TargetID;
66706f32e7eSjoerg }
66806f32e7eSjoerg 
getPassSubstitution(AnalysisID ID) const66906f32e7eSjoerg IdentifyingPassPtr TargetPassConfig::getPassSubstitution(AnalysisID ID) const {
67006f32e7eSjoerg   DenseMap<AnalysisID, IdentifyingPassPtr>::const_iterator
67106f32e7eSjoerg     I = Impl->TargetPasses.find(ID);
67206f32e7eSjoerg   if (I == Impl->TargetPasses.end())
67306f32e7eSjoerg     return ID;
67406f32e7eSjoerg   return I->second;
67506f32e7eSjoerg }
67606f32e7eSjoerg 
isPassSubstitutedOrOverridden(AnalysisID ID) const67706f32e7eSjoerg bool TargetPassConfig::isPassSubstitutedOrOverridden(AnalysisID ID) const {
67806f32e7eSjoerg   IdentifyingPassPtr TargetID = getPassSubstitution(ID);
67906f32e7eSjoerg   IdentifyingPassPtr FinalPtr = overridePass(ID, TargetID);
68006f32e7eSjoerg   return !FinalPtr.isValid() || FinalPtr.isInstance() ||
68106f32e7eSjoerg       FinalPtr.getID() != ID;
68206f32e7eSjoerg }
68306f32e7eSjoerg 
68406f32e7eSjoerg /// Add a pass to the PassManager if that pass is supposed to be run.  If the
68506f32e7eSjoerg /// Started/Stopped flags indicate either that the compilation should start at
68606f32e7eSjoerg /// a later pass or that it should stop after an earlier pass, then do not add
68706f32e7eSjoerg /// the pass.  Finally, compare the current pass against the StartAfter
68806f32e7eSjoerg /// and StopAfter options and change the Started/Stopped flags accordingly.
addPass(Pass * P,bool verifyAfter)689*da58b97aSjoerg void TargetPassConfig::addPass(Pass *P, bool verifyAfter) {
69006f32e7eSjoerg   assert(!Initialized && "PassConfig is immutable");
69106f32e7eSjoerg 
69206f32e7eSjoerg   // Cache the Pass ID here in case the pass manager finds this pass is
69306f32e7eSjoerg   // redundant with ones already scheduled / available, and deletes it.
69406f32e7eSjoerg   // Fundamentally, once we add the pass to the manager, we no longer own it
69506f32e7eSjoerg   // and shouldn't reference it.
69606f32e7eSjoerg   AnalysisID PassID = P->getPassID();
69706f32e7eSjoerg 
69806f32e7eSjoerg   if (StartBefore == PassID && StartBeforeCount++ == StartBeforeInstanceNum)
69906f32e7eSjoerg     Started = true;
70006f32e7eSjoerg   if (StopBefore == PassID && StopBeforeCount++ == StopBeforeInstanceNum)
70106f32e7eSjoerg     Stopped = true;
70206f32e7eSjoerg   if (Started && !Stopped) {
703*da58b97aSjoerg     if (AddingMachinePasses)
704*da58b97aSjoerg       addMachinePrePasses();
70506f32e7eSjoerg     std::string Banner;
70606f32e7eSjoerg     // Construct banner message before PM->add() as that may delete the pass.
707*da58b97aSjoerg     if (AddingMachinePasses && verifyAfter)
70806f32e7eSjoerg       Banner = std::string("After ") + std::string(P->getPassName());
70906f32e7eSjoerg     PM->add(P);
710*da58b97aSjoerg     if (AddingMachinePasses)
711*da58b97aSjoerg       addMachinePostPasses(Banner, /*AllowVerify*/ verifyAfter);
71206f32e7eSjoerg 
71306f32e7eSjoerg     // Add the passes after the pass P if there is any.
714*da58b97aSjoerg     for (const auto &IP : Impl->InsertedPasses) {
71506f32e7eSjoerg       if (IP.TargetPassID == PassID)
716*da58b97aSjoerg         addPass(IP.getInsertedPass(), IP.VerifyAfter);
71706f32e7eSjoerg     }
71806f32e7eSjoerg   } else {
71906f32e7eSjoerg     delete P;
72006f32e7eSjoerg   }
72106f32e7eSjoerg 
72206f32e7eSjoerg   if (StopAfter == PassID && StopAfterCount++ == StopAfterInstanceNum)
72306f32e7eSjoerg     Stopped = true;
72406f32e7eSjoerg 
72506f32e7eSjoerg   if (StartAfter == PassID && StartAfterCount++ == StartAfterInstanceNum)
72606f32e7eSjoerg     Started = true;
72706f32e7eSjoerg   if (Stopped && !Started)
72806f32e7eSjoerg     report_fatal_error("Cannot stop compilation after pass that is not run");
72906f32e7eSjoerg }
73006f32e7eSjoerg 
73106f32e7eSjoerg /// Add a CodeGen pass at this point in the pipeline after checking for target
73206f32e7eSjoerg /// and command line overrides.
73306f32e7eSjoerg ///
73406f32e7eSjoerg /// addPass cannot return a pointer to the pass instance because is internal the
73506f32e7eSjoerg /// PassManager and the instance we create here may already be freed.
addPass(AnalysisID PassID,bool verifyAfter)736*da58b97aSjoerg AnalysisID TargetPassConfig::addPass(AnalysisID PassID, bool verifyAfter) {
73706f32e7eSjoerg   IdentifyingPassPtr TargetID = getPassSubstitution(PassID);
73806f32e7eSjoerg   IdentifyingPassPtr FinalPtr = overridePass(PassID, TargetID);
73906f32e7eSjoerg   if (!FinalPtr.isValid())
74006f32e7eSjoerg     return nullptr;
74106f32e7eSjoerg 
74206f32e7eSjoerg   Pass *P;
74306f32e7eSjoerg   if (FinalPtr.isInstance())
74406f32e7eSjoerg     P = FinalPtr.getInstance();
74506f32e7eSjoerg   else {
74606f32e7eSjoerg     P = Pass::createPass(FinalPtr.getID());
74706f32e7eSjoerg     if (!P)
74806f32e7eSjoerg       llvm_unreachable("Pass ID not registered");
74906f32e7eSjoerg   }
75006f32e7eSjoerg   AnalysisID FinalID = P->getPassID();
751*da58b97aSjoerg   addPass(P, verifyAfter); // Ends the lifetime of P.
75206f32e7eSjoerg 
75306f32e7eSjoerg   return FinalID;
75406f32e7eSjoerg }
75506f32e7eSjoerg 
printAndVerify(const std::string & Banner)75606f32e7eSjoerg void TargetPassConfig::printAndVerify(const std::string &Banner) {
75706f32e7eSjoerg   addPrintPass(Banner);
75806f32e7eSjoerg   addVerifyPass(Banner);
75906f32e7eSjoerg }
76006f32e7eSjoerg 
addPrintPass(const std::string & Banner)76106f32e7eSjoerg void TargetPassConfig::addPrintPass(const std::string &Banner) {
762*da58b97aSjoerg   if (PrintAfterISel)
76306f32e7eSjoerg     PM->add(createMachineFunctionPrinterPass(dbgs(), Banner));
76406f32e7eSjoerg }
76506f32e7eSjoerg 
addVerifyPass(const std::string & Banner)76606f32e7eSjoerg void TargetPassConfig::addVerifyPass(const std::string &Banner) {
76706f32e7eSjoerg   bool Verify = VerifyMachineCode == cl::BOU_TRUE;
76806f32e7eSjoerg #ifdef EXPENSIVE_CHECKS
76906f32e7eSjoerg   if (VerifyMachineCode == cl::BOU_UNSET)
77006f32e7eSjoerg     Verify = TM->isMachineVerifierClean();
77106f32e7eSjoerg #endif
77206f32e7eSjoerg   if (Verify)
77306f32e7eSjoerg     PM->add(createMachineVerifierPass(Banner));
77406f32e7eSjoerg }
77506f32e7eSjoerg 
addDebugifyPass()776*da58b97aSjoerg void TargetPassConfig::addDebugifyPass() {
777*da58b97aSjoerg   PM->add(createDebugifyMachineModulePass());
778*da58b97aSjoerg }
779*da58b97aSjoerg 
addStripDebugPass()780*da58b97aSjoerg void TargetPassConfig::addStripDebugPass() {
781*da58b97aSjoerg   PM->add(createStripDebugMachineModulePass(/*OnlyDebugified=*/true));
782*da58b97aSjoerg }
783*da58b97aSjoerg 
addCheckDebugPass()784*da58b97aSjoerg void TargetPassConfig::addCheckDebugPass() {
785*da58b97aSjoerg   PM->add(createCheckDebugMachineModulePass());
786*da58b97aSjoerg }
787*da58b97aSjoerg 
addMachinePrePasses(bool AllowDebugify)788*da58b97aSjoerg void TargetPassConfig::addMachinePrePasses(bool AllowDebugify) {
789*da58b97aSjoerg   if (AllowDebugify && DebugifyIsSafe &&
790*da58b97aSjoerg       (DebugifyAndStripAll == cl::BOU_TRUE ||
791*da58b97aSjoerg        DebugifyCheckAndStripAll == cl::BOU_TRUE))
792*da58b97aSjoerg     addDebugifyPass();
793*da58b97aSjoerg }
794*da58b97aSjoerg 
addMachinePostPasses(const std::string & Banner,bool AllowVerify,bool AllowStrip)795*da58b97aSjoerg void TargetPassConfig::addMachinePostPasses(const std::string &Banner,
796*da58b97aSjoerg                                             bool AllowVerify, bool AllowStrip) {
797*da58b97aSjoerg   if (DebugifyIsSafe) {
798*da58b97aSjoerg     if (DebugifyCheckAndStripAll == cl::BOU_TRUE) {
799*da58b97aSjoerg       addCheckDebugPass();
800*da58b97aSjoerg       addStripDebugPass();
801*da58b97aSjoerg     } else if (DebugifyAndStripAll == cl::BOU_TRUE)
802*da58b97aSjoerg       addStripDebugPass();
803*da58b97aSjoerg   }
804*da58b97aSjoerg   if (AllowVerify)
805*da58b97aSjoerg     addVerifyPass(Banner);
806*da58b97aSjoerg }
807*da58b97aSjoerg 
80806f32e7eSjoerg /// Add common target configurable passes that perform LLVM IR to IR transforms
80906f32e7eSjoerg /// following machine independent optimization.
addIRPasses()81006f32e7eSjoerg void TargetPassConfig::addIRPasses() {
811*da58b97aSjoerg   // Before running any passes, run the verifier to determine if the input
812*da58b97aSjoerg   // coming from the front-end and/or optimizer is valid.
813*da58b97aSjoerg   if (!DisableVerify)
814*da58b97aSjoerg     addPass(createVerifierPass());
815*da58b97aSjoerg 
816*da58b97aSjoerg   if (getOptLevel() != CodeGenOpt::None) {
81706f32e7eSjoerg     switch (UseCFLAA) {
81806f32e7eSjoerg     case CFLAAType::Steensgaard:
81906f32e7eSjoerg       addPass(createCFLSteensAAWrapperPass());
82006f32e7eSjoerg       break;
82106f32e7eSjoerg     case CFLAAType::Andersen:
82206f32e7eSjoerg       addPass(createCFLAndersAAWrapperPass());
82306f32e7eSjoerg       break;
82406f32e7eSjoerg     case CFLAAType::Both:
82506f32e7eSjoerg       addPass(createCFLAndersAAWrapperPass());
82606f32e7eSjoerg       addPass(createCFLSteensAAWrapperPass());
82706f32e7eSjoerg       break;
82806f32e7eSjoerg     default:
82906f32e7eSjoerg       break;
83006f32e7eSjoerg     }
83106f32e7eSjoerg 
83206f32e7eSjoerg     // Basic AliasAnalysis support.
83306f32e7eSjoerg     // Add TypeBasedAliasAnalysis before BasicAliasAnalysis so that
83406f32e7eSjoerg     // BasicAliasAnalysis wins if they disagree. This is intended to help
83506f32e7eSjoerg     // support "obvious" type-punning idioms.
83606f32e7eSjoerg     addPass(createTypeBasedAAWrapperPass());
83706f32e7eSjoerg     addPass(createScopedNoAliasAAWrapperPass());
83806f32e7eSjoerg     addPass(createBasicAAWrapperPass());
83906f32e7eSjoerg 
84006f32e7eSjoerg     // Run loop strength reduction before anything else.
841*da58b97aSjoerg     if (!DisableLSR) {
842*da58b97aSjoerg       addPass(createCanonicalizeFreezeInLoopsPass());
84306f32e7eSjoerg       addPass(createLoopStrengthReducePass());
84406f32e7eSjoerg       if (PrintLSR)
845*da58b97aSjoerg         addPass(createPrintFunctionPass(dbgs(),
846*da58b97aSjoerg                                         "\n\n*** Code after LSR ***\n"));
84706f32e7eSjoerg     }
84806f32e7eSjoerg 
84906f32e7eSjoerg     // The MergeICmpsPass tries to create memcmp calls by grouping sequences of
85006f32e7eSjoerg     // loads and compares. ExpandMemCmpPass then tries to expand those calls
85106f32e7eSjoerg     // into optimally-sized loads and compares. The transforms are enabled by a
85206f32e7eSjoerg     // target lowering hook.
85306f32e7eSjoerg     if (!DisableMergeICmps)
85406f32e7eSjoerg       addPass(createMergeICmpsLegacyPass());
85506f32e7eSjoerg     addPass(createExpandMemCmpPass());
85606f32e7eSjoerg   }
85706f32e7eSjoerg 
85806f32e7eSjoerg   // Run GC lowering passes for builtin collectors
85906f32e7eSjoerg   // TODO: add a pass insertion point here
86006f32e7eSjoerg   addPass(createGCLoweringPass());
86106f32e7eSjoerg   addPass(createShadowStackGCLoweringPass());
86206f32e7eSjoerg   addPass(createLowerConstantIntrinsicsPass());
86306f32e7eSjoerg 
86406f32e7eSjoerg   // Make sure that no unreachable blocks are instruction selected.
86506f32e7eSjoerg   addPass(createUnreachableBlockEliminationPass());
86606f32e7eSjoerg 
86706f32e7eSjoerg   // Prepare expensive constants for SelectionDAG.
86806f32e7eSjoerg   if (getOptLevel() != CodeGenOpt::None && !DisableConstantHoisting)
86906f32e7eSjoerg     addPass(createConstantHoistingPass());
87006f32e7eSjoerg 
871*da58b97aSjoerg   if (getOptLevel() != CodeGenOpt::None)
872*da58b97aSjoerg     addPass(createReplaceWithVeclibLegacyPass());
873*da58b97aSjoerg 
87406f32e7eSjoerg   if (getOptLevel() != CodeGenOpt::None && !DisablePartialLibcallInlining)
87506f32e7eSjoerg     addPass(createPartiallyInlineLibCallsPass());
87606f32e7eSjoerg 
877*da58b97aSjoerg   // Expand vector predication intrinsics into standard IR instructions.
878*da58b97aSjoerg   // This pass has to run before ScalarizeMaskedMemIntrin and ExpandReduction
879*da58b97aSjoerg   // passes since it emits those kinds of intrinsics.
880*da58b97aSjoerg   addPass(createExpandVectorPredicationPass());
88106f32e7eSjoerg 
88206f32e7eSjoerg   // Add scalarization of target's unsupported masked memory intrinsics pass.
88306f32e7eSjoerg   // the unsupported intrinsic will be replaced with a chain of basic blocks,
88406f32e7eSjoerg   // that stores/loads element one-by-one if the appropriate mask bit is set.
885*da58b97aSjoerg   addPass(createScalarizeMaskedMemIntrinLegacyPass());
88606f32e7eSjoerg 
88706f32e7eSjoerg   // Expand reduction intrinsics into shuffle sequences if the target wants to.
888*da58b97aSjoerg   // Allow disabling it for testing purposes.
889*da58b97aSjoerg   if (!DisableExpandReductions)
89006f32e7eSjoerg     addPass(createExpandReductionsPass());
89106f32e7eSjoerg }
89206f32e7eSjoerg 
89306f32e7eSjoerg /// Turn exception handling constructs into something the code generators can
89406f32e7eSjoerg /// handle.
addPassesToHandleExceptions()89506f32e7eSjoerg void TargetPassConfig::addPassesToHandleExceptions() {
89606f32e7eSjoerg   const MCAsmInfo *MCAI = TM->getMCAsmInfo();
89706f32e7eSjoerg   assert(MCAI && "No MCAsmInfo");
89806f32e7eSjoerg   switch (MCAI->getExceptionHandlingType()) {
89906f32e7eSjoerg   case ExceptionHandling::SjLj:
90006f32e7eSjoerg     // SjLj piggy-backs on dwarf for this bit. The cleanups done apply to both
90106f32e7eSjoerg     // Dwarf EH prepare needs to be run after SjLj prepare. Otherwise,
90206f32e7eSjoerg     // catch info can get misplaced when a selector ends up more than one block
90306f32e7eSjoerg     // removed from the parent invoke(s). This could happen when a landing
90406f32e7eSjoerg     // pad is shared by multiple invokes and is also a target of a normal
90506f32e7eSjoerg     // edge from elsewhere.
906*da58b97aSjoerg     addPass(createSjLjEHPreparePass(TM));
90706f32e7eSjoerg     LLVM_FALLTHROUGH;
90806f32e7eSjoerg   case ExceptionHandling::DwarfCFI:
90906f32e7eSjoerg   case ExceptionHandling::ARM:
910*da58b97aSjoerg   case ExceptionHandling::AIX:
911*da58b97aSjoerg     addPass(createDwarfEHPass(getOptLevel()));
91206f32e7eSjoerg     break;
91306f32e7eSjoerg   case ExceptionHandling::WinEH:
91406f32e7eSjoerg     // We support using both GCC-style and MSVC-style exceptions on Windows, so
91506f32e7eSjoerg     // add both preparation passes. Each pass will only actually run if it
91606f32e7eSjoerg     // recognizes the personality function.
91706f32e7eSjoerg     addPass(createWinEHPass());
918*da58b97aSjoerg     addPass(createDwarfEHPass(getOptLevel()));
91906f32e7eSjoerg     break;
92006f32e7eSjoerg   case ExceptionHandling::Wasm:
92106f32e7eSjoerg     // Wasm EH uses Windows EH instructions, but it does not need to demote PHIs
92206f32e7eSjoerg     // on catchpads and cleanuppads because it does not outline them into
92306f32e7eSjoerg     // funclets. Catchswitch blocks are not lowered in SelectionDAG, so we
92406f32e7eSjoerg     // should remove PHIs there.
92506f32e7eSjoerg     addPass(createWinEHPass(/*DemoteCatchSwitchPHIOnly=*/false));
92606f32e7eSjoerg     addPass(createWasmEHPass());
92706f32e7eSjoerg     break;
92806f32e7eSjoerg   case ExceptionHandling::None:
92906f32e7eSjoerg     addPass(createLowerInvokePass());
93006f32e7eSjoerg 
93106f32e7eSjoerg     // The lower invoke pass may create unreachable code. Remove it.
93206f32e7eSjoerg     addPass(createUnreachableBlockEliminationPass());
93306f32e7eSjoerg     break;
93406f32e7eSjoerg   }
93506f32e7eSjoerg }
93606f32e7eSjoerg 
93706f32e7eSjoerg /// Add pass to prepare the LLVM IR for code generation. This should be done
93806f32e7eSjoerg /// before exception handling preparation passes.
addCodeGenPrepare()93906f32e7eSjoerg void TargetPassConfig::addCodeGenPrepare() {
94006f32e7eSjoerg   if (getOptLevel() != CodeGenOpt::None && !DisableCGP)
94106f32e7eSjoerg     addPass(createCodeGenPreparePass());
94206f32e7eSjoerg   addPass(createRewriteSymbolsPass());
94306f32e7eSjoerg }
94406f32e7eSjoerg 
94506f32e7eSjoerg /// Add common passes that perform LLVM IR to IR transforms in preparation for
94606f32e7eSjoerg /// instruction selection.
addISelPrepare()94706f32e7eSjoerg void TargetPassConfig::addISelPrepare() {
94806f32e7eSjoerg   addPreISel();
94906f32e7eSjoerg 
95006f32e7eSjoerg   // Force codegen to run according to the callgraph.
95106f32e7eSjoerg   if (requiresCodeGenSCCOrder())
95206f32e7eSjoerg     addPass(new DummyCGSCCPass);
95306f32e7eSjoerg 
95406f32e7eSjoerg   // Add both the safe stack and the stack protection passes: each of them will
95506f32e7eSjoerg   // only protect functions that have corresponding attributes.
95606f32e7eSjoerg   addPass(createSafeStackPass());
95706f32e7eSjoerg   addPass(createStackProtectorPass());
95806f32e7eSjoerg 
95906f32e7eSjoerg   if (PrintISelInput)
96006f32e7eSjoerg     addPass(createPrintFunctionPass(
96106f32e7eSjoerg         dbgs(), "\n\n*** Final LLVM Code input to ISel ***\n"));
96206f32e7eSjoerg 
96306f32e7eSjoerg   // All passes which modify the LLVM IR are now complete; run the verifier
96406f32e7eSjoerg   // to ensure that the IR is valid.
96506f32e7eSjoerg   if (!DisableVerify)
96606f32e7eSjoerg     addPass(createVerifierPass());
96706f32e7eSjoerg }
96806f32e7eSjoerg 
addCoreISelPasses()96906f32e7eSjoerg bool TargetPassConfig::addCoreISelPasses() {
97006f32e7eSjoerg   // Enable FastISel with -fast-isel, but allow that to be overridden.
97106f32e7eSjoerg   TM->setO0WantsFastISel(EnableFastISelOption != cl::BOU_FALSE);
97206f32e7eSjoerg 
97306f32e7eSjoerg   // Determine an instruction selector.
97406f32e7eSjoerg   enum class SelectorType { SelectionDAG, FastISel, GlobalISel };
97506f32e7eSjoerg   SelectorType Selector;
97606f32e7eSjoerg 
97706f32e7eSjoerg   if (EnableFastISelOption == cl::BOU_TRUE)
97806f32e7eSjoerg     Selector = SelectorType::FastISel;
97906f32e7eSjoerg   else if (EnableGlobalISelOption == cl::BOU_TRUE ||
98006f32e7eSjoerg            (TM->Options.EnableGlobalISel &&
98106f32e7eSjoerg             EnableGlobalISelOption != cl::BOU_FALSE))
98206f32e7eSjoerg     Selector = SelectorType::GlobalISel;
98306f32e7eSjoerg   else if (TM->getOptLevel() == CodeGenOpt::None && TM->getO0WantsFastISel())
98406f32e7eSjoerg     Selector = SelectorType::FastISel;
98506f32e7eSjoerg   else
98606f32e7eSjoerg     Selector = SelectorType::SelectionDAG;
98706f32e7eSjoerg 
98806f32e7eSjoerg   // Set consistently TM->Options.EnableFastISel and EnableGlobalISel.
98906f32e7eSjoerg   if (Selector == SelectorType::FastISel) {
99006f32e7eSjoerg     TM->setFastISel(true);
99106f32e7eSjoerg     TM->setGlobalISel(false);
99206f32e7eSjoerg   } else if (Selector == SelectorType::GlobalISel) {
99306f32e7eSjoerg     TM->setFastISel(false);
99406f32e7eSjoerg     TM->setGlobalISel(true);
99506f32e7eSjoerg   }
99606f32e7eSjoerg 
997*da58b97aSjoerg   // FIXME: Injecting into the DAGISel pipeline seems to cause issues with
998*da58b97aSjoerg   //        analyses needing to be re-run. This can result in being unable to
999*da58b97aSjoerg   //        schedule passes (particularly with 'Function Alias Analysis
1000*da58b97aSjoerg   //        Results'). It's not entirely clear why but AFAICT this seems to be
1001*da58b97aSjoerg   //        due to one FunctionPassManager not being able to use analyses from a
1002*da58b97aSjoerg   //        previous one. As we're injecting a ModulePass we break the usual
1003*da58b97aSjoerg   //        pass manager into two. GlobalISel with the fallback path disabled
1004*da58b97aSjoerg   //        and -run-pass seem to be unaffected. The majority of GlobalISel
1005*da58b97aSjoerg   //        testing uses -run-pass so this probably isn't too bad.
1006*da58b97aSjoerg   SaveAndRestore<bool> SavedDebugifyIsSafe(DebugifyIsSafe);
1007*da58b97aSjoerg   if (Selector != SelectorType::GlobalISel || !isGlobalISelAbortEnabled())
1008*da58b97aSjoerg     DebugifyIsSafe = false;
1009*da58b97aSjoerg 
101006f32e7eSjoerg   // Add instruction selector passes.
101106f32e7eSjoerg   if (Selector == SelectorType::GlobalISel) {
101206f32e7eSjoerg     SaveAndRestore<bool> SavedAddingMachinePasses(AddingMachinePasses, true);
101306f32e7eSjoerg     if (addIRTranslator())
101406f32e7eSjoerg       return true;
101506f32e7eSjoerg 
101606f32e7eSjoerg     addPreLegalizeMachineIR();
101706f32e7eSjoerg 
101806f32e7eSjoerg     if (addLegalizeMachineIR())
101906f32e7eSjoerg       return true;
102006f32e7eSjoerg 
102106f32e7eSjoerg     // Before running the register bank selector, ask the target if it
102206f32e7eSjoerg     // wants to run some passes.
102306f32e7eSjoerg     addPreRegBankSelect();
102406f32e7eSjoerg 
102506f32e7eSjoerg     if (addRegBankSelect())
102606f32e7eSjoerg       return true;
102706f32e7eSjoerg 
102806f32e7eSjoerg     addPreGlobalInstructionSelect();
102906f32e7eSjoerg 
103006f32e7eSjoerg     if (addGlobalInstructionSelect())
103106f32e7eSjoerg       return true;
103206f32e7eSjoerg 
103306f32e7eSjoerg     // Pass to reset the MachineFunction if the ISel failed.
103406f32e7eSjoerg     addPass(createResetMachineFunctionPass(
103506f32e7eSjoerg         reportDiagnosticWhenGlobalISelFallback(), isGlobalISelAbortEnabled()));
103606f32e7eSjoerg 
103706f32e7eSjoerg     // Provide a fallback path when we do not want to abort on
103806f32e7eSjoerg     // not-yet-supported input.
103906f32e7eSjoerg     if (!isGlobalISelAbortEnabled() && addInstSelector())
104006f32e7eSjoerg       return true;
104106f32e7eSjoerg 
104206f32e7eSjoerg   } else if (addInstSelector())
104306f32e7eSjoerg     return true;
104406f32e7eSjoerg 
104506f32e7eSjoerg   // Expand pseudo-instructions emitted by ISel. Don't run the verifier before
104606f32e7eSjoerg   // FinalizeISel.
104706f32e7eSjoerg   addPass(&FinalizeISelID);
104806f32e7eSjoerg 
104906f32e7eSjoerg   // Print the instruction selected machine code...
105006f32e7eSjoerg   printAndVerify("After Instruction Selection");
105106f32e7eSjoerg 
105206f32e7eSjoerg   return false;
105306f32e7eSjoerg }
105406f32e7eSjoerg 
addISelPasses()105506f32e7eSjoerg bool TargetPassConfig::addISelPasses() {
105606f32e7eSjoerg   if (TM->useEmulatedTLS())
105706f32e7eSjoerg     addPass(createLowerEmuTLSPass());
105806f32e7eSjoerg 
105906f32e7eSjoerg   addPass(createPreISelIntrinsicLoweringPass());
1060*da58b97aSjoerg   PM->add(createTargetTransformInfoWrapperPass(TM->getTargetIRAnalysis()));
106106f32e7eSjoerg   addIRPasses();
106206f32e7eSjoerg   addCodeGenPrepare();
106306f32e7eSjoerg   addPassesToHandleExceptions();
106406f32e7eSjoerg   addISelPrepare();
106506f32e7eSjoerg 
106606f32e7eSjoerg   return addCoreISelPasses();
106706f32e7eSjoerg }
106806f32e7eSjoerg 
106906f32e7eSjoerg /// -regalloc=... command line option.
useDefaultRegisterAllocator()107006f32e7eSjoerg static FunctionPass *useDefaultRegisterAllocator() { return nullptr; }
107106f32e7eSjoerg static cl::opt<RegisterRegAlloc::FunctionPassCtor, false,
107206f32e7eSjoerg                RegisterPassParser<RegisterRegAlloc>>
107306f32e7eSjoerg     RegAlloc("regalloc", cl::Hidden, cl::init(&useDefaultRegisterAllocator),
107406f32e7eSjoerg              cl::desc("Register allocator to use"));
107506f32e7eSjoerg 
107606f32e7eSjoerg /// Add the complete set of target-independent postISel code generator passes.
107706f32e7eSjoerg ///
107806f32e7eSjoerg /// This can be read as the standard order of major LLVM CodeGen stages. Stages
107906f32e7eSjoerg /// with nontrivial configuration or multiple passes are broken out below in
108006f32e7eSjoerg /// add%Stage routines.
108106f32e7eSjoerg ///
108206f32e7eSjoerg /// Any TargetPassConfig::addXX routine may be overriden by the Target. The
108306f32e7eSjoerg /// addPre/Post methods with empty header implementations allow injecting
108406f32e7eSjoerg /// target-specific fixups just before or after major stages. Additionally,
108506f32e7eSjoerg /// targets have the flexibility to change pass order within a stage by
108606f32e7eSjoerg /// overriding default implementation of add%Stage routines below. Each
108706f32e7eSjoerg /// technique has maintainability tradeoffs because alternate pass orders are
108806f32e7eSjoerg /// not well supported. addPre/Post works better if the target pass is easily
108906f32e7eSjoerg /// tied to a common pass. But if it has subtle dependencies on multiple passes,
109006f32e7eSjoerg /// the target should override the stage instead.
109106f32e7eSjoerg ///
109206f32e7eSjoerg /// TODO: We could use a single addPre/Post(ID) hook to allow pass injection
109306f32e7eSjoerg /// before/after any target-independent pass. But it's currently overkill.
addMachinePasses()109406f32e7eSjoerg void TargetPassConfig::addMachinePasses() {
109506f32e7eSjoerg   AddingMachinePasses = true;
109606f32e7eSjoerg 
109706f32e7eSjoerg   // Add passes that optimize machine instructions in SSA form.
109806f32e7eSjoerg   if (getOptLevel() != CodeGenOpt::None) {
109906f32e7eSjoerg     addMachineSSAOptimization();
110006f32e7eSjoerg   } else {
110106f32e7eSjoerg     // If the target requests it, assign local variables to stack slots relative
110206f32e7eSjoerg     // to one another and simplify frame index references where possible.
1103*da58b97aSjoerg     addPass(&LocalStackSlotAllocationID);
110406f32e7eSjoerg   }
110506f32e7eSjoerg 
110606f32e7eSjoerg   if (TM->Options.EnableIPRA)
110706f32e7eSjoerg     addPass(createRegUsageInfoPropPass());
110806f32e7eSjoerg 
110906f32e7eSjoerg   // Run pre-ra passes.
111006f32e7eSjoerg   addPreRegAlloc();
111106f32e7eSjoerg 
1112*da58b97aSjoerg   // Debugifying the register allocator passes seems to provoke some
1113*da58b97aSjoerg   // non-determinism that affects CodeGen and there doesn't seem to be a point
1114*da58b97aSjoerg   // where it becomes safe again so stop debugifying here.
1115*da58b97aSjoerg   DebugifyIsSafe = false;
1116*da58b97aSjoerg 
111706f32e7eSjoerg   // Run register allocation and passes that are tightly coupled with it,
111806f32e7eSjoerg   // including phi elimination and scheduling.
111906f32e7eSjoerg   if (getOptimizeRegAlloc())
112006f32e7eSjoerg     addOptimizedRegAlloc();
112106f32e7eSjoerg   else
112206f32e7eSjoerg     addFastRegAlloc();
112306f32e7eSjoerg 
112406f32e7eSjoerg   // Run post-ra passes.
112506f32e7eSjoerg   addPostRegAlloc();
112606f32e7eSjoerg 
1127*da58b97aSjoerg   addPass(&FixupStatepointCallerSavedID);
1128*da58b97aSjoerg 
112906f32e7eSjoerg   // Insert prolog/epilog code.  Eliminate abstract frame index references...
113006f32e7eSjoerg   if (getOptLevel() != CodeGenOpt::None) {
113106f32e7eSjoerg     addPass(&PostRAMachineSinkingID);
113206f32e7eSjoerg     addPass(&ShrinkWrapID);
113306f32e7eSjoerg   }
113406f32e7eSjoerg 
113506f32e7eSjoerg   // Prolog/Epilog inserter needs a TargetMachine to instantiate. But only
113606f32e7eSjoerg   // do so if it hasn't been disabled, substituted, or overridden.
113706f32e7eSjoerg   if (!isPassSubstitutedOrOverridden(&PrologEpilogCodeInserterID))
113806f32e7eSjoerg       addPass(createPrologEpilogInserterPass());
113906f32e7eSjoerg 
114006f32e7eSjoerg   /// Add passes that optimize machine instructions after register allocation.
114106f32e7eSjoerg   if (getOptLevel() != CodeGenOpt::None)
114206f32e7eSjoerg     addMachineLateOptimization();
114306f32e7eSjoerg 
114406f32e7eSjoerg   // Expand pseudo instructions before second scheduling pass.
114506f32e7eSjoerg   addPass(&ExpandPostRAPseudosID);
114606f32e7eSjoerg 
114706f32e7eSjoerg   // Run pre-sched2 passes.
114806f32e7eSjoerg   addPreSched2();
114906f32e7eSjoerg 
115006f32e7eSjoerg   if (EnableImplicitNullChecks)
115106f32e7eSjoerg     addPass(&ImplicitNullChecksID);
115206f32e7eSjoerg 
115306f32e7eSjoerg   // Second pass scheduler.
115406f32e7eSjoerg   // Let Target optionally insert this pass by itself at some other
115506f32e7eSjoerg   // point.
115606f32e7eSjoerg   if (getOptLevel() != CodeGenOpt::None &&
115706f32e7eSjoerg       !TM->targetSchedulesPostRAScheduling()) {
115806f32e7eSjoerg     if (MISchedPostRA)
115906f32e7eSjoerg       addPass(&PostMachineSchedulerID);
116006f32e7eSjoerg     else
116106f32e7eSjoerg       addPass(&PostRASchedulerID);
116206f32e7eSjoerg   }
116306f32e7eSjoerg 
116406f32e7eSjoerg   // GC
116506f32e7eSjoerg   if (addGCPasses()) {
116606f32e7eSjoerg     if (PrintGCInfo)
1167*da58b97aSjoerg       addPass(createGCInfoPrinter(dbgs()), false);
116806f32e7eSjoerg   }
116906f32e7eSjoerg 
117006f32e7eSjoerg   // Basic block placement.
117106f32e7eSjoerg   if (getOptLevel() != CodeGenOpt::None)
117206f32e7eSjoerg     addBlockPlacement();
117306f32e7eSjoerg 
1174*da58b97aSjoerg   // Insert before XRay Instrumentation.
1175*da58b97aSjoerg   addPass(&FEntryInserterID);
1176*da58b97aSjoerg 
1177*da58b97aSjoerg   addPass(&XRayInstrumentationID);
1178*da58b97aSjoerg   addPass(&PatchableFunctionID);
1179*da58b97aSjoerg 
1180*da58b97aSjoerg   if (EnableFSDiscriminator && !FSNoFinalDiscrim)
1181*da58b97aSjoerg     addPass(createMIRAddFSDiscriminatorsPass(PASS_LAST_DIS_BIT_BEG,
1182*da58b97aSjoerg                                              PASS_LAST_DIS_BIT_END));
1183*da58b97aSjoerg 
118406f32e7eSjoerg   addPreEmitPass();
118506f32e7eSjoerg 
118606f32e7eSjoerg   if (TM->Options.EnableIPRA)
118706f32e7eSjoerg     // Collect register usage information and produce a register mask of
118806f32e7eSjoerg     // clobbered registers, to be used to optimize call sites.
118906f32e7eSjoerg     addPass(createRegUsageInfoCollector());
119006f32e7eSjoerg 
1191*da58b97aSjoerg   // FIXME: Some backends are incompatible with running the verifier after
1192*da58b97aSjoerg   // addPreEmitPass.  Maybe only pass "false" here for those targets?
119306f32e7eSjoerg   addPass(&FuncletLayoutID, false);
119406f32e7eSjoerg 
119506f32e7eSjoerg   addPass(&StackMapLivenessID, false);
119606f32e7eSjoerg   addPass(&LiveDebugValuesID, false);
119706f32e7eSjoerg 
119806f32e7eSjoerg   if (TM->Options.EnableMachineOutliner && getOptLevel() != CodeGenOpt::None &&
1199*da58b97aSjoerg       EnableMachineOutliner != RunOutliner::NeverOutline) {
1200*da58b97aSjoerg     bool RunOnAllFunctions =
1201*da58b97aSjoerg         (EnableMachineOutliner == RunOutliner::AlwaysOutline);
1202*da58b97aSjoerg     bool AddOutliner =
1203*da58b97aSjoerg         RunOnAllFunctions || TM->Options.SupportsDefaultOutlining;
120406f32e7eSjoerg     if (AddOutliner)
120506f32e7eSjoerg       addPass(createMachineOutlinerPass(RunOnAllFunctions));
120606f32e7eSjoerg   }
120706f32e7eSjoerg 
1208*da58b97aSjoerg   // Machine function splitter uses the basic block sections feature. Both
1209*da58b97aSjoerg   // cannot be enabled at the same time. Basic block sections takes precedence.
1210*da58b97aSjoerg   // FIXME: In principle, BasicBlockSection::Labels and splitting can used
1211*da58b97aSjoerg   // together. Update this check once we have addressed any issues.
1212*da58b97aSjoerg   if (TM->getBBSectionsType() != llvm::BasicBlockSection::None) {
1213*da58b97aSjoerg     addPass(llvm::createBasicBlockSectionsPass(TM->getBBSectionsFuncListBuf()));
1214*da58b97aSjoerg   } else if (TM->Options.EnableMachineFunctionSplitter ||
1215*da58b97aSjoerg              EnableMachineFunctionSplitter) {
1216*da58b97aSjoerg     addPass(createMachineFunctionSplitterPass());
1217*da58b97aSjoerg   }
1218*da58b97aSjoerg 
121906f32e7eSjoerg   // Add passes that directly emit MI after all other MI passes.
122006f32e7eSjoerg   addPreEmitPass2();
122106f32e7eSjoerg 
1222*da58b97aSjoerg   // Insert pseudo probe annotation for callsite profiling
1223*da58b97aSjoerg   if (TM->Options.PseudoProbeForProfiling)
1224*da58b97aSjoerg     addPass(createPseudoProbeInserter());
1225*da58b97aSjoerg 
122606f32e7eSjoerg   AddingMachinePasses = false;
122706f32e7eSjoerg }
122806f32e7eSjoerg 
122906f32e7eSjoerg /// Add passes that optimize machine instructions in SSA form.
addMachineSSAOptimization()123006f32e7eSjoerg void TargetPassConfig::addMachineSSAOptimization() {
123106f32e7eSjoerg   // Pre-ra tail duplication.
123206f32e7eSjoerg   addPass(&EarlyTailDuplicateID);
123306f32e7eSjoerg 
123406f32e7eSjoerg   // Optimize PHIs before DCE: removing dead PHI cycles may make more
123506f32e7eSjoerg   // instructions dead.
1236*da58b97aSjoerg   addPass(&OptimizePHIsID);
123706f32e7eSjoerg 
123806f32e7eSjoerg   // This pass merges large allocas. StackSlotColoring is a different pass
123906f32e7eSjoerg   // which merges spill slots.
1240*da58b97aSjoerg   addPass(&StackColoringID);
124106f32e7eSjoerg 
124206f32e7eSjoerg   // If the target requests it, assign local variables to stack slots relative
124306f32e7eSjoerg   // to one another and simplify frame index references where possible.
1244*da58b97aSjoerg   addPass(&LocalStackSlotAllocationID);
124506f32e7eSjoerg 
124606f32e7eSjoerg   // With optimization, dead code should already be eliminated. However
124706f32e7eSjoerg   // there is one known exception: lowered code for arguments that are only
124806f32e7eSjoerg   // used by tail calls, where the tail calls reuse the incoming stack
124906f32e7eSjoerg   // arguments directly (see t11 in test/CodeGen/X86/sibcall.ll).
125006f32e7eSjoerg   addPass(&DeadMachineInstructionElimID);
125106f32e7eSjoerg 
125206f32e7eSjoerg   // Allow targets to insert passes that improve instruction level parallelism,
125306f32e7eSjoerg   // like if-conversion. Such passes will typically need dominator trees and
125406f32e7eSjoerg   // loop info, just like LICM and CSE below.
125506f32e7eSjoerg   addILPOpts();
125606f32e7eSjoerg 
1257*da58b97aSjoerg   addPass(&EarlyMachineLICMID);
1258*da58b97aSjoerg   addPass(&MachineCSEID);
125906f32e7eSjoerg 
126006f32e7eSjoerg   addPass(&MachineSinkingID);
126106f32e7eSjoerg 
126206f32e7eSjoerg   addPass(&PeepholeOptimizerID);
126306f32e7eSjoerg   // Clean-up the dead code that may have been generated by peephole
126406f32e7eSjoerg   // rewriting.
126506f32e7eSjoerg   addPass(&DeadMachineInstructionElimID);
126606f32e7eSjoerg }
126706f32e7eSjoerg 
126806f32e7eSjoerg //===---------------------------------------------------------------------===//
126906f32e7eSjoerg /// Register Allocation Pass Configuration
127006f32e7eSjoerg //===---------------------------------------------------------------------===//
127106f32e7eSjoerg 
getOptimizeRegAlloc() const127206f32e7eSjoerg bool TargetPassConfig::getOptimizeRegAlloc() const {
127306f32e7eSjoerg   switch (OptimizeRegAlloc) {
127406f32e7eSjoerg   case cl::BOU_UNSET: return getOptLevel() != CodeGenOpt::None;
127506f32e7eSjoerg   case cl::BOU_TRUE:  return true;
127606f32e7eSjoerg   case cl::BOU_FALSE: return false;
127706f32e7eSjoerg   }
127806f32e7eSjoerg   llvm_unreachable("Invalid optimize-regalloc state");
127906f32e7eSjoerg }
128006f32e7eSjoerg 
128106f32e7eSjoerg /// A dummy default pass factory indicates whether the register allocator is
128206f32e7eSjoerg /// overridden on the command line.
128306f32e7eSjoerg static llvm::once_flag InitializeDefaultRegisterAllocatorFlag;
128406f32e7eSjoerg 
128506f32e7eSjoerg static RegisterRegAlloc
128606f32e7eSjoerg defaultRegAlloc("default",
128706f32e7eSjoerg                 "pick register allocator based on -O option",
128806f32e7eSjoerg                 useDefaultRegisterAllocator);
128906f32e7eSjoerg 
initializeDefaultRegisterAllocatorOnce()129006f32e7eSjoerg static void initializeDefaultRegisterAllocatorOnce() {
129106f32e7eSjoerg   if (!RegisterRegAlloc::getDefault())
129206f32e7eSjoerg     RegisterRegAlloc::setDefault(RegAlloc);
129306f32e7eSjoerg }
129406f32e7eSjoerg 
129506f32e7eSjoerg /// Instantiate the default register allocator pass for this target for either
129606f32e7eSjoerg /// the optimized or unoptimized allocation path. This will be added to the pass
129706f32e7eSjoerg /// manager by addFastRegAlloc in the unoptimized case or addOptimizedRegAlloc
129806f32e7eSjoerg /// in the optimized case.
129906f32e7eSjoerg ///
130006f32e7eSjoerg /// A target that uses the standard regalloc pass order for fast or optimized
130106f32e7eSjoerg /// allocation may still override this for per-target regalloc
130206f32e7eSjoerg /// selection. But -regalloc=... always takes precedence.
createTargetRegisterAllocator(bool Optimized)130306f32e7eSjoerg FunctionPass *TargetPassConfig::createTargetRegisterAllocator(bool Optimized) {
130406f32e7eSjoerg   if (Optimized)
130506f32e7eSjoerg     return createGreedyRegisterAllocator();
130606f32e7eSjoerg   else
130706f32e7eSjoerg     return createFastRegisterAllocator();
130806f32e7eSjoerg }
130906f32e7eSjoerg 
131006f32e7eSjoerg /// Find and instantiate the register allocation pass requested by this target
131106f32e7eSjoerg /// at the current optimization level.  Different register allocators are
131206f32e7eSjoerg /// defined as separate passes because they may require different analysis.
131306f32e7eSjoerg ///
131406f32e7eSjoerg /// This helper ensures that the regalloc= option is always available,
131506f32e7eSjoerg /// even for targets that override the default allocator.
131606f32e7eSjoerg ///
131706f32e7eSjoerg /// FIXME: When MachinePassRegistry register pass IDs instead of function ptrs,
131806f32e7eSjoerg /// this can be folded into addPass.
createRegAllocPass(bool Optimized)131906f32e7eSjoerg FunctionPass *TargetPassConfig::createRegAllocPass(bool Optimized) {
132006f32e7eSjoerg   // Initialize the global default.
132106f32e7eSjoerg   llvm::call_once(InitializeDefaultRegisterAllocatorFlag,
132206f32e7eSjoerg                   initializeDefaultRegisterAllocatorOnce);
132306f32e7eSjoerg 
132406f32e7eSjoerg   RegisterRegAlloc::FunctionPassCtor Ctor = RegisterRegAlloc::getDefault();
132506f32e7eSjoerg   if (Ctor != useDefaultRegisterAllocator)
132606f32e7eSjoerg     return Ctor();
132706f32e7eSjoerg 
132806f32e7eSjoerg   // With no -regalloc= override, ask the target for a regalloc pass.
132906f32e7eSjoerg   return createTargetRegisterAllocator(Optimized);
133006f32e7eSjoerg }
133106f32e7eSjoerg 
addRegAssignAndRewriteFast()1332*da58b97aSjoerg bool TargetPassConfig::addRegAssignAndRewriteFast() {
133306f32e7eSjoerg   if (RegAlloc != &useDefaultRegisterAllocator &&
133406f32e7eSjoerg       RegAlloc != &createFastRegisterAllocator)
133506f32e7eSjoerg     report_fatal_error("Must use fast (default) register allocator for unoptimized regalloc.");
133606f32e7eSjoerg 
133706f32e7eSjoerg   addPass(createRegAllocPass(false));
1338*da58b97aSjoerg 
1339*da58b97aSjoerg   // Allow targets to change the register assignments after
1340*da58b97aSjoerg   // fast register allocation.
1341*da58b97aSjoerg   addPostFastRegAllocRewrite();
134206f32e7eSjoerg   return true;
134306f32e7eSjoerg }
134406f32e7eSjoerg 
addRegAssignAndRewriteOptimized()1345*da58b97aSjoerg bool TargetPassConfig::addRegAssignAndRewriteOptimized() {
134606f32e7eSjoerg   // Add the selected register allocation pass.
134706f32e7eSjoerg   addPass(createRegAllocPass(true));
134806f32e7eSjoerg 
134906f32e7eSjoerg   // Allow targets to change the register assignments before rewriting.
135006f32e7eSjoerg   addPreRewrite();
135106f32e7eSjoerg 
135206f32e7eSjoerg   // Finally rewrite virtual registers.
135306f32e7eSjoerg   addPass(&VirtRegRewriterID);
135406f32e7eSjoerg 
135506f32e7eSjoerg   return true;
135606f32e7eSjoerg }
135706f32e7eSjoerg 
135806f32e7eSjoerg /// Return true if the default global register allocator is in use and
135906f32e7eSjoerg /// has not be overriden on the command line with '-regalloc=...'
usingDefaultRegAlloc() const136006f32e7eSjoerg bool TargetPassConfig::usingDefaultRegAlloc() const {
136106f32e7eSjoerg   return RegAlloc.getNumOccurrences() == 0;
136206f32e7eSjoerg }
136306f32e7eSjoerg 
136406f32e7eSjoerg /// Add the minimum set of target-independent passes that are required for
136506f32e7eSjoerg /// register allocation. No coalescing or scheduling.
addFastRegAlloc()136606f32e7eSjoerg void TargetPassConfig::addFastRegAlloc() {
136706f32e7eSjoerg   addPass(&PHIEliminationID, false);
136806f32e7eSjoerg   addPass(&TwoAddressInstructionPassID, false);
136906f32e7eSjoerg 
1370*da58b97aSjoerg   addRegAssignAndRewriteFast();
137106f32e7eSjoerg }
137206f32e7eSjoerg 
137306f32e7eSjoerg /// Add standard target-independent passes that are tightly coupled with
137406f32e7eSjoerg /// optimized register allocation, including coalescing, machine instruction
137506f32e7eSjoerg /// scheduling, and register allocation itself.
addOptimizedRegAlloc()137606f32e7eSjoerg void TargetPassConfig::addOptimizedRegAlloc() {
137706f32e7eSjoerg   addPass(&DetectDeadLanesID, false);
137806f32e7eSjoerg 
137906f32e7eSjoerg   addPass(&ProcessImplicitDefsID, false);
138006f32e7eSjoerg 
138106f32e7eSjoerg   // LiveVariables currently requires pure SSA form.
138206f32e7eSjoerg   //
138306f32e7eSjoerg   // FIXME: Once TwoAddressInstruction pass no longer uses kill flags,
138406f32e7eSjoerg   // LiveVariables can be removed completely, and LiveIntervals can be directly
138506f32e7eSjoerg   // computed. (We still either need to regenerate kill flags after regalloc, or
138606f32e7eSjoerg   // preferably fix the scavenger to not depend on them).
1387*da58b97aSjoerg   // FIXME: UnreachableMachineBlockElim is a dependant pass of LiveVariables.
1388*da58b97aSjoerg   // When LiveVariables is removed this has to be removed/moved either.
1389*da58b97aSjoerg   // Explicit addition of UnreachableMachineBlockElim allows stopping before or
1390*da58b97aSjoerg   // after it with -stop-before/-stop-after.
1391*da58b97aSjoerg   addPass(&UnreachableMachineBlockElimID, false);
139206f32e7eSjoerg   addPass(&LiveVariablesID, false);
139306f32e7eSjoerg 
139406f32e7eSjoerg   // Edge splitting is smarter with machine loop info.
139506f32e7eSjoerg   addPass(&MachineLoopInfoID, false);
139606f32e7eSjoerg   addPass(&PHIEliminationID, false);
139706f32e7eSjoerg 
139806f32e7eSjoerg   // Eventually, we want to run LiveIntervals before PHI elimination.
139906f32e7eSjoerg   if (EarlyLiveIntervals)
140006f32e7eSjoerg     addPass(&LiveIntervalsID, false);
140106f32e7eSjoerg 
140206f32e7eSjoerg   addPass(&TwoAddressInstructionPassID, false);
140306f32e7eSjoerg   addPass(&RegisterCoalescerID);
140406f32e7eSjoerg 
140506f32e7eSjoerg   // The machine scheduler may accidentally create disconnected components
140606f32e7eSjoerg   // when moving subregister definitions around, avoid this by splitting them to
140706f32e7eSjoerg   // separate vregs before. Splitting can also improve reg. allocation quality.
140806f32e7eSjoerg   addPass(&RenameIndependentSubregsID);
140906f32e7eSjoerg 
141006f32e7eSjoerg   // PreRA instruction scheduling.
141106f32e7eSjoerg   addPass(&MachineSchedulerID);
141206f32e7eSjoerg 
1413*da58b97aSjoerg   if (addRegAssignAndRewriteOptimized()) {
1414*da58b97aSjoerg     // Perform stack slot coloring and post-ra machine LICM.
1415*da58b97aSjoerg     //
1416*da58b97aSjoerg     // FIXME: Re-enable coloring with register when it's capable of adding
1417*da58b97aSjoerg     // kill markers.
1418*da58b97aSjoerg     addPass(&StackSlotColoringID);
1419*da58b97aSjoerg 
142006f32e7eSjoerg     // Allow targets to expand pseudo instructions depending on the choice of
142106f32e7eSjoerg     // registers before MachineCopyPropagation.
142206f32e7eSjoerg     addPostRewrite();
142306f32e7eSjoerg 
142406f32e7eSjoerg     // Copy propagate to forward register uses and try to eliminate COPYs that
142506f32e7eSjoerg     // were not coalesced.
142606f32e7eSjoerg     addPass(&MachineCopyPropagationID);
142706f32e7eSjoerg 
142806f32e7eSjoerg     // Run post-ra machine LICM to hoist reloads / remats.
142906f32e7eSjoerg     //
143006f32e7eSjoerg     // FIXME: can this move into MachineLateOptimization?
143106f32e7eSjoerg     addPass(&MachineLICMID);
143206f32e7eSjoerg   }
143306f32e7eSjoerg }
143406f32e7eSjoerg 
143506f32e7eSjoerg //===---------------------------------------------------------------------===//
143606f32e7eSjoerg /// Post RegAlloc Pass Configuration
143706f32e7eSjoerg //===---------------------------------------------------------------------===//
143806f32e7eSjoerg 
143906f32e7eSjoerg /// Add passes that optimize machine instructions after register allocation.
addMachineLateOptimization()144006f32e7eSjoerg void TargetPassConfig::addMachineLateOptimization() {
144106f32e7eSjoerg   // Branch folding must be run after regalloc and prolog/epilog insertion.
144206f32e7eSjoerg   addPass(&BranchFolderPassID);
144306f32e7eSjoerg 
144406f32e7eSjoerg   // Tail duplication.
144506f32e7eSjoerg   // Note that duplicating tail just increases code size and degrades
144606f32e7eSjoerg   // performance for targets that require Structured Control Flow.
144706f32e7eSjoerg   // In addition it can also make CFG irreducible. Thus we disable it.
144806f32e7eSjoerg   if (!TM->requiresStructuredCFG())
144906f32e7eSjoerg     addPass(&TailDuplicateID);
145006f32e7eSjoerg 
145106f32e7eSjoerg   // Copy propagation.
145206f32e7eSjoerg   addPass(&MachineCopyPropagationID);
145306f32e7eSjoerg }
145406f32e7eSjoerg 
145506f32e7eSjoerg /// Add standard GC passes.
addGCPasses()145606f32e7eSjoerg bool TargetPassConfig::addGCPasses() {
145706f32e7eSjoerg   addPass(&GCMachineCodeAnalysisID, false);
145806f32e7eSjoerg   return true;
145906f32e7eSjoerg }
146006f32e7eSjoerg 
146106f32e7eSjoerg /// Add standard basic block placement passes.
addBlockPlacement()146206f32e7eSjoerg void TargetPassConfig::addBlockPlacement() {
146306f32e7eSjoerg   if (addPass(&MachineBlockPlacementID)) {
146406f32e7eSjoerg     // Run a separate pass to collect block placement statistics.
146506f32e7eSjoerg     if (EnableBlockPlacementStats)
146606f32e7eSjoerg       addPass(&MachineBlockPlacementStatsID);
146706f32e7eSjoerg   }
146806f32e7eSjoerg }
146906f32e7eSjoerg 
147006f32e7eSjoerg //===---------------------------------------------------------------------===//
147106f32e7eSjoerg /// GlobalISel Configuration
147206f32e7eSjoerg //===---------------------------------------------------------------------===//
isGlobalISelAbortEnabled() const147306f32e7eSjoerg bool TargetPassConfig::isGlobalISelAbortEnabled() const {
147406f32e7eSjoerg   return TM->Options.GlobalISelAbort == GlobalISelAbortMode::Enable;
147506f32e7eSjoerg }
147606f32e7eSjoerg 
reportDiagnosticWhenGlobalISelFallback() const147706f32e7eSjoerg bool TargetPassConfig::reportDiagnosticWhenGlobalISelFallback() const {
147806f32e7eSjoerg   return TM->Options.GlobalISelAbort == GlobalISelAbortMode::DisableWithDiag;
147906f32e7eSjoerg }
148006f32e7eSjoerg 
isGISelCSEEnabled() const148106f32e7eSjoerg bool TargetPassConfig::isGISelCSEEnabled() const {
148206f32e7eSjoerg   return true;
148306f32e7eSjoerg }
148406f32e7eSjoerg 
getCSEConfig() const148506f32e7eSjoerg std::unique_ptr<CSEConfigBase> TargetPassConfig::getCSEConfig() const {
148606f32e7eSjoerg   return std::make_unique<CSEConfigBase>();
148706f32e7eSjoerg }
1488