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/CFLAndersAliasAnalysis.h"
200b57cec5SDimitry Andric #include "llvm/Analysis/CFLSteensAliasAnalysis.h"
210b57cec5SDimitry Andric #include "llvm/Analysis/CallGraphSCCPass.h"
220b57cec5SDimitry Andric #include "llvm/Analysis/ScopedNoAliasAA.h"
230b57cec5SDimitry Andric #include "llvm/Analysis/TargetTransformInfo.h"
240b57cec5SDimitry Andric #include "llvm/Analysis/TypeBasedAliasAnalysis.h"
250b57cec5SDimitry Andric #include "llvm/CodeGen/CSEConfigBase.h"
260b57cec5SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h"
270b57cec5SDimitry Andric #include "llvm/CodeGen/MachinePassRegistry.h"
280b57cec5SDimitry Andric #include "llvm/CodeGen/Passes.h"
290b57cec5SDimitry Andric #include "llvm/CodeGen/RegAllocRegistry.h"
300b57cec5SDimitry Andric #include "llvm/IR/IRPrintingPasses.h"
310b57cec5SDimitry Andric #include "llvm/IR/LegacyPassManager.h"
32af732203SDimitry Andric #include "llvm/IR/PassInstrumentation.h"
330b57cec5SDimitry Andric #include "llvm/IR/Verifier.h"
34480093f4SDimitry Andric #include "llvm/InitializePasses.h"
350b57cec5SDimitry Andric #include "llvm/MC/MCAsmInfo.h"
360b57cec5SDimitry Andric #include "llvm/MC/MCTargetOptions.h"
370b57cec5SDimitry Andric #include "llvm/Pass.h"
380b57cec5SDimitry Andric #include "llvm/Support/CodeGen.h"
390b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h"
400b57cec5SDimitry Andric #include "llvm/Support/Compiler.h"
410b57cec5SDimitry Andric #include "llvm/Support/Debug.h"
42*5f7ddb14SDimitry Andric #include "llvm/Support/Discriminator.h"
430b57cec5SDimitry Andric #include "llvm/Support/ErrorHandling.h"
440b57cec5SDimitry Andric #include "llvm/Support/SaveAndRestore.h"
45480093f4SDimitry Andric #include "llvm/Support/Threading.h"
46af732203SDimitry Andric #include "llvm/Target/CGPassBuilderOption.h"
470b57cec5SDimitry Andric #include "llvm/Target/TargetMachine.h"
480b57cec5SDimitry Andric #include "llvm/Transforms/Scalar.h"
490b57cec5SDimitry Andric #include "llvm/Transforms/Utils.h"
500b57cec5SDimitry Andric #include "llvm/Transforms/Utils/SymbolRewriter.h"
510b57cec5SDimitry Andric #include <cassert>
520b57cec5SDimitry Andric #include <string>
530b57cec5SDimitry Andric 
540b57cec5SDimitry Andric using namespace llvm;
550b57cec5SDimitry Andric 
568bcb0991SDimitry Andric static cl::opt<bool>
578bcb0991SDimitry Andric     EnableIPRA("enable-ipra", cl::init(false), cl::Hidden,
580b57cec5SDimitry Andric                cl::desc("Enable interprocedural register allocation "
590b57cec5SDimitry Andric                         "to reduce load/store at procedure calls."));
600b57cec5SDimitry Andric static cl::opt<bool> DisablePostRASched("disable-post-ra", cl::Hidden,
610b57cec5SDimitry Andric     cl::desc("Disable Post Regalloc Scheduler"));
620b57cec5SDimitry Andric static cl::opt<bool> DisableBranchFold("disable-branch-fold", cl::Hidden,
630b57cec5SDimitry Andric     cl::desc("Disable branch folding"));
640b57cec5SDimitry Andric static cl::opt<bool> DisableTailDuplicate("disable-tail-duplicate", cl::Hidden,
650b57cec5SDimitry Andric     cl::desc("Disable tail duplication"));
660b57cec5SDimitry Andric static cl::opt<bool> DisableEarlyTailDup("disable-early-taildup", cl::Hidden,
670b57cec5SDimitry Andric     cl::desc("Disable pre-register allocation tail duplication"));
680b57cec5SDimitry Andric static cl::opt<bool> DisableBlockPlacement("disable-block-placement",
690b57cec5SDimitry Andric     cl::Hidden, cl::desc("Disable probability-driven block placement"));
700b57cec5SDimitry Andric static cl::opt<bool> EnableBlockPlacementStats("enable-block-placement-stats",
710b57cec5SDimitry Andric     cl::Hidden, cl::desc("Collect probability-driven block placement stats"));
720b57cec5SDimitry Andric static cl::opt<bool> DisableSSC("disable-ssc", cl::Hidden,
730b57cec5SDimitry Andric     cl::desc("Disable Stack Slot Coloring"));
740b57cec5SDimitry Andric static cl::opt<bool> DisableMachineDCE("disable-machine-dce", cl::Hidden,
750b57cec5SDimitry Andric     cl::desc("Disable Machine Dead Code Elimination"));
760b57cec5SDimitry Andric static cl::opt<bool> DisableEarlyIfConversion("disable-early-ifcvt", cl::Hidden,
770b57cec5SDimitry Andric     cl::desc("Disable Early If-conversion"));
780b57cec5SDimitry Andric static cl::opt<bool> DisableMachineLICM("disable-machine-licm", cl::Hidden,
790b57cec5SDimitry Andric     cl::desc("Disable Machine LICM"));
800b57cec5SDimitry Andric static cl::opt<bool> DisableMachineCSE("disable-machine-cse", cl::Hidden,
810b57cec5SDimitry Andric     cl::desc("Disable Machine Common Subexpression Elimination"));
820b57cec5SDimitry Andric static cl::opt<cl::boolOrDefault> OptimizeRegAlloc(
830b57cec5SDimitry Andric     "optimize-regalloc", cl::Hidden,
840b57cec5SDimitry Andric     cl::desc("Enable optimized register allocation compilation path."));
850b57cec5SDimitry Andric static cl::opt<bool> DisablePostRAMachineLICM("disable-postra-machine-licm",
860b57cec5SDimitry Andric     cl::Hidden,
870b57cec5SDimitry Andric     cl::desc("Disable Machine LICM"));
880b57cec5SDimitry Andric static cl::opt<bool> DisableMachineSink("disable-machine-sink", cl::Hidden,
890b57cec5SDimitry Andric     cl::desc("Disable Machine Sinking"));
900b57cec5SDimitry Andric static cl::opt<bool> DisablePostRAMachineSink("disable-postra-machine-sink",
910b57cec5SDimitry Andric     cl::Hidden,
920b57cec5SDimitry Andric     cl::desc("Disable PostRA Machine Sinking"));
930b57cec5SDimitry Andric static cl::opt<bool> DisableLSR("disable-lsr", cl::Hidden,
940b57cec5SDimitry Andric     cl::desc("Disable Loop Strength Reduction Pass"));
950b57cec5SDimitry Andric static cl::opt<bool> DisableConstantHoisting("disable-constant-hoisting",
960b57cec5SDimitry Andric     cl::Hidden, cl::desc("Disable ConstantHoisting"));
970b57cec5SDimitry Andric static cl::opt<bool> DisableCGP("disable-cgp", cl::Hidden,
980b57cec5SDimitry Andric     cl::desc("Disable Codegen Prepare"));
990b57cec5SDimitry Andric static cl::opt<bool> DisableCopyProp("disable-copyprop", cl::Hidden,
1000b57cec5SDimitry Andric     cl::desc("Disable Copy Propagation pass"));
1010b57cec5SDimitry Andric static cl::opt<bool> DisablePartialLibcallInlining("disable-partial-libcall-inlining",
1020b57cec5SDimitry Andric     cl::Hidden, cl::desc("Disable Partial Libcall Inlining"));
1030b57cec5SDimitry Andric static cl::opt<bool> EnableImplicitNullChecks(
1040b57cec5SDimitry Andric     "enable-implicit-null-checks",
1050b57cec5SDimitry Andric     cl::desc("Fold null checks into faulting memory operations"),
1060b57cec5SDimitry Andric     cl::init(false), cl::Hidden);
1070b57cec5SDimitry Andric static cl::opt<bool> DisableMergeICmps("disable-mergeicmps",
1080b57cec5SDimitry Andric     cl::desc("Disable MergeICmps Pass"),
1090b57cec5SDimitry Andric     cl::init(false), cl::Hidden);
1100b57cec5SDimitry Andric static cl::opt<bool> PrintLSR("print-lsr-output", cl::Hidden,
1110b57cec5SDimitry Andric     cl::desc("Print LLVM IR produced by the loop-reduce pass"));
1120b57cec5SDimitry Andric static cl::opt<bool> PrintISelInput("print-isel-input", cl::Hidden,
1130b57cec5SDimitry Andric     cl::desc("Print LLVM IR input to isel pass"));
1140b57cec5SDimitry Andric static cl::opt<bool> PrintGCInfo("print-gc", cl::Hidden,
1150b57cec5SDimitry Andric     cl::desc("Dump garbage collector data"));
1160b57cec5SDimitry Andric static cl::opt<cl::boolOrDefault>
1170b57cec5SDimitry Andric     VerifyMachineCode("verify-machineinstrs", cl::Hidden,
1180b57cec5SDimitry Andric                       cl::desc("Verify generated machine code"),
1190b57cec5SDimitry Andric                       cl::ZeroOrMore);
1205ffd83dbSDimitry Andric static cl::opt<cl::boolOrDefault> DebugifyAndStripAll(
1215ffd83dbSDimitry Andric     "debugify-and-strip-all-safe", cl::Hidden,
1225ffd83dbSDimitry Andric     cl::desc(
1235ffd83dbSDimitry Andric         "Debugify MIR before and Strip debug after "
1245ffd83dbSDimitry Andric         "each pass except those known to be unsafe when debug info is present"),
1255ffd83dbSDimitry Andric     cl::ZeroOrMore);
126af732203SDimitry Andric static cl::opt<cl::boolOrDefault> DebugifyCheckAndStripAll(
127af732203SDimitry Andric     "debugify-check-and-strip-all-safe", cl::Hidden,
128af732203SDimitry Andric     cl::desc(
129af732203SDimitry Andric         "Debugify MIR before, by checking and stripping the debug info after, "
130af732203SDimitry Andric         "each pass except those known to be unsafe when debug info is present"),
131af732203SDimitry Andric     cl::ZeroOrMore);
1320b57cec5SDimitry Andric // Enable or disable the MachineOutliner.
1330b57cec5SDimitry Andric static cl::opt<RunOutliner> EnableMachineOutliner(
1340b57cec5SDimitry Andric     "enable-machine-outliner", cl::desc("Enable the machine outliner"),
135af732203SDimitry Andric     cl::Hidden, cl::ValueOptional, cl::init(RunOutliner::TargetDefault),
136af732203SDimitry Andric     cl::values(clEnumValN(RunOutliner::AlwaysOutline, "always",
1370b57cec5SDimitry Andric                           "Run on all functions guaranteed to be beneficial"),
138af732203SDimitry Andric                clEnumValN(RunOutliner::NeverOutline, "never",
139af732203SDimitry Andric                           "Disable all outlining"),
1400b57cec5SDimitry Andric                // Sentinel value for unspecified option.
141af732203SDimitry Andric                clEnumValN(RunOutliner::AlwaysOutline, "", "")));
1420b57cec5SDimitry Andric // Enable or disable FastISel. Both options are needed, because
1430b57cec5SDimitry Andric // FastISel is enabled by default with -fast, and we wish to be
1440b57cec5SDimitry Andric // able to enable or disable fast-isel independently from -O0.
1450b57cec5SDimitry Andric static cl::opt<cl::boolOrDefault>
1460b57cec5SDimitry Andric EnableFastISelOption("fast-isel", cl::Hidden,
1470b57cec5SDimitry Andric   cl::desc("Enable the \"fast\" instruction selector"));
1480b57cec5SDimitry Andric 
1490b57cec5SDimitry Andric static cl::opt<cl::boolOrDefault> EnableGlobalISelOption(
1500b57cec5SDimitry Andric     "global-isel", cl::Hidden,
1510b57cec5SDimitry Andric     cl::desc("Enable the \"global\" instruction selector"));
1520b57cec5SDimitry Andric 
153af732203SDimitry Andric // FIXME: remove this after switching to NPM or GlobalISel, whichever gets there
154af732203SDimitry Andric //        first...
155af732203SDimitry Andric static cl::opt<bool>
156af732203SDimitry Andric     PrintAfterISel("print-after-isel", cl::init(false), cl::Hidden,
157af732203SDimitry Andric                    cl::desc("Print machine instrs after ISel"));
1580b57cec5SDimitry Andric 
1590b57cec5SDimitry Andric static cl::opt<GlobalISelAbortMode> EnableGlobalISelAbort(
1600b57cec5SDimitry Andric     "global-isel-abort", cl::Hidden,
1610b57cec5SDimitry Andric     cl::desc("Enable abort calls when \"global\" instruction selection "
1620b57cec5SDimitry Andric              "fails to lower/select an instruction"),
1630b57cec5SDimitry Andric     cl::values(
1640b57cec5SDimitry Andric         clEnumValN(GlobalISelAbortMode::Disable, "0", "Disable the abort"),
1650b57cec5SDimitry Andric         clEnumValN(GlobalISelAbortMode::Enable, "1", "Enable the abort"),
1660b57cec5SDimitry Andric         clEnumValN(GlobalISelAbortMode::DisableWithDiag, "2",
1670b57cec5SDimitry Andric                    "Disable the abort but emit a diagnostic on failure")));
1680b57cec5SDimitry Andric 
169*5f7ddb14SDimitry Andric // An option that disables inserting FS-AFDO discriminators before emit.
170*5f7ddb14SDimitry Andric // This is mainly for debugging and tuning purpose.
171*5f7ddb14SDimitry Andric static cl::opt<bool>
172*5f7ddb14SDimitry Andric     FSNoFinalDiscrim("fs-no-final-discrim", cl::init(false), cl::Hidden,
173*5f7ddb14SDimitry Andric                      cl::desc("Do not insert FS-AFDO discriminators before "
174*5f7ddb14SDimitry Andric                               "emit."));
175*5f7ddb14SDimitry Andric 
1760b57cec5SDimitry Andric // Temporary option to allow experimenting with MachineScheduler as a post-RA
1770b57cec5SDimitry Andric // scheduler. Targets can "properly" enable this with
1780b57cec5SDimitry Andric // substitutePass(&PostRASchedulerID, &PostMachineSchedulerID).
1790b57cec5SDimitry Andric // Targets can return true in targetSchedulesPostRAScheduling() and
1800b57cec5SDimitry Andric // insert a PostRA scheduling pass wherever it wants.
1818bcb0991SDimitry Andric static cl::opt<bool> MISchedPostRA(
1828bcb0991SDimitry Andric     "misched-postra", cl::Hidden,
1838bcb0991SDimitry Andric     cl::desc(
1848bcb0991SDimitry Andric         "Run MachineScheduler post regalloc (independent of preRA sched)"));
1850b57cec5SDimitry Andric 
1860b57cec5SDimitry Andric // Experimental option to run live interval analysis early.
1870b57cec5SDimitry Andric static cl::opt<bool> EarlyLiveIntervals("early-live-intervals", cl::Hidden,
1880b57cec5SDimitry Andric     cl::desc("Run live interval analysis earlier in the pipeline"));
1890b57cec5SDimitry Andric 
1900b57cec5SDimitry Andric // Experimental option to use CFL-AA in codegen
1910b57cec5SDimitry Andric static cl::opt<CFLAAType> UseCFLAA(
1920b57cec5SDimitry Andric     "use-cfl-aa-in-codegen", cl::init(CFLAAType::None), cl::Hidden,
1930b57cec5SDimitry Andric     cl::desc("Enable the new, experimental CFL alias analysis in CodeGen"),
1940b57cec5SDimitry Andric     cl::values(clEnumValN(CFLAAType::None, "none", "Disable CFL-AA"),
1950b57cec5SDimitry Andric                clEnumValN(CFLAAType::Steensgaard, "steens",
1960b57cec5SDimitry Andric                           "Enable unification-based CFL-AA"),
1970b57cec5SDimitry Andric                clEnumValN(CFLAAType::Andersen, "anders",
1980b57cec5SDimitry Andric                           "Enable inclusion-based CFL-AA"),
1990b57cec5SDimitry Andric                clEnumValN(CFLAAType::Both, "both",
2000b57cec5SDimitry Andric                           "Enable both variants of CFL-AA")));
2010b57cec5SDimitry Andric 
2020b57cec5SDimitry Andric /// Option names for limiting the codegen pipeline.
2030b57cec5SDimitry Andric /// Those are used in error reporting and we didn't want
2040b57cec5SDimitry Andric /// to duplicate their names all over the place.
205480093f4SDimitry Andric static const char StartAfterOptName[] = "start-after";
206480093f4SDimitry Andric static const char StartBeforeOptName[] = "start-before";
207480093f4SDimitry Andric static const char StopAfterOptName[] = "stop-after";
208480093f4SDimitry Andric static const char StopBeforeOptName[] = "stop-before";
2090b57cec5SDimitry Andric 
2100b57cec5SDimitry Andric static cl::opt<std::string>
2110b57cec5SDimitry Andric     StartAfterOpt(StringRef(StartAfterOptName),
2120b57cec5SDimitry Andric                   cl::desc("Resume compilation after a specific pass"),
2130b57cec5SDimitry Andric                   cl::value_desc("pass-name"), cl::init(""), cl::Hidden);
2140b57cec5SDimitry Andric 
2150b57cec5SDimitry Andric static cl::opt<std::string>
2160b57cec5SDimitry Andric     StartBeforeOpt(StringRef(StartBeforeOptName),
2170b57cec5SDimitry Andric                    cl::desc("Resume compilation before a specific pass"),
2180b57cec5SDimitry Andric                    cl::value_desc("pass-name"), cl::init(""), cl::Hidden);
2190b57cec5SDimitry Andric 
2200b57cec5SDimitry Andric static cl::opt<std::string>
2210b57cec5SDimitry Andric     StopAfterOpt(StringRef(StopAfterOptName),
2220b57cec5SDimitry Andric                  cl::desc("Stop 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     StopBeforeOpt(StringRef(StopBeforeOptName),
2270b57cec5SDimitry Andric                   cl::desc("Stop compilation before a specific pass"),
2280b57cec5SDimitry Andric                   cl::value_desc("pass-name"), cl::init(""), cl::Hidden);
2290b57cec5SDimitry Andric 
230af732203SDimitry Andric /// Enable the machine function splitter pass.
231af732203SDimitry Andric static cl::opt<bool> EnableMachineFunctionSplitter(
232af732203SDimitry Andric     "enable-split-machine-functions", cl::Hidden,
233af732203SDimitry Andric     cl::desc("Split out cold blocks from machine functions based on profile "
234af732203SDimitry Andric              "information."));
235af732203SDimitry Andric 
236af732203SDimitry Andric /// Disable the expand reductions pass for testing.
237af732203SDimitry Andric static cl::opt<bool> DisableExpandReductions(
238af732203SDimitry Andric     "disable-expand-reductions", cl::init(false), cl::Hidden,
239af732203SDimitry Andric     cl::desc("Disable the expand reduction intrinsics pass from running"));
240af732203SDimitry Andric 
2410b57cec5SDimitry Andric /// Allow standard passes to be disabled by command line options. This supports
2420b57cec5SDimitry Andric /// simple binary flags that either suppress the pass or do nothing.
2430b57cec5SDimitry Andric /// i.e. -disable-mypass=false has no effect.
2440b57cec5SDimitry Andric /// These should be converted to boolOrDefault in order to use applyOverride.
applyDisable(IdentifyingPassPtr PassID,bool Override)2450b57cec5SDimitry Andric static IdentifyingPassPtr applyDisable(IdentifyingPassPtr PassID,
2460b57cec5SDimitry Andric                                        bool Override) {
2470b57cec5SDimitry Andric   if (Override)
2480b57cec5SDimitry Andric     return IdentifyingPassPtr();
2490b57cec5SDimitry Andric   return PassID;
2500b57cec5SDimitry Andric }
2510b57cec5SDimitry Andric 
2520b57cec5SDimitry Andric /// Allow standard passes to be disabled by the command line, regardless of who
2530b57cec5SDimitry Andric /// is adding the pass.
2540b57cec5SDimitry Andric ///
2550b57cec5SDimitry Andric /// StandardID is the pass identified in the standard pass pipeline and provided
2560b57cec5SDimitry Andric /// to addPass(). It may be a target-specific ID in the case that the target
2570b57cec5SDimitry Andric /// directly adds its own pass, but in that case we harmlessly fall through.
2580b57cec5SDimitry Andric ///
2590b57cec5SDimitry Andric /// TargetID is the pass that the target has configured to override StandardID.
2600b57cec5SDimitry Andric ///
2610b57cec5SDimitry Andric /// StandardID may be a pseudo ID. In that case TargetID is the name of the real
2620b57cec5SDimitry Andric /// pass to run. This allows multiple options to control a single pass depending
2630b57cec5SDimitry Andric /// on where in the pipeline that pass is added.
overridePass(AnalysisID StandardID,IdentifyingPassPtr TargetID)2640b57cec5SDimitry Andric static IdentifyingPassPtr overridePass(AnalysisID StandardID,
2650b57cec5SDimitry Andric                                        IdentifyingPassPtr TargetID) {
2660b57cec5SDimitry Andric   if (StandardID == &PostRASchedulerID)
2670b57cec5SDimitry Andric     return applyDisable(TargetID, DisablePostRASched);
2680b57cec5SDimitry Andric 
2690b57cec5SDimitry Andric   if (StandardID == &BranchFolderPassID)
2700b57cec5SDimitry Andric     return applyDisable(TargetID, DisableBranchFold);
2710b57cec5SDimitry Andric 
2720b57cec5SDimitry Andric   if (StandardID == &TailDuplicateID)
2730b57cec5SDimitry Andric     return applyDisable(TargetID, DisableTailDuplicate);
2740b57cec5SDimitry Andric 
2750b57cec5SDimitry Andric   if (StandardID == &EarlyTailDuplicateID)
2760b57cec5SDimitry Andric     return applyDisable(TargetID, DisableEarlyTailDup);
2770b57cec5SDimitry Andric 
2780b57cec5SDimitry Andric   if (StandardID == &MachineBlockPlacementID)
2790b57cec5SDimitry Andric     return applyDisable(TargetID, DisableBlockPlacement);
2800b57cec5SDimitry Andric 
2810b57cec5SDimitry Andric   if (StandardID == &StackSlotColoringID)
2820b57cec5SDimitry Andric     return applyDisable(TargetID, DisableSSC);
2830b57cec5SDimitry Andric 
2840b57cec5SDimitry Andric   if (StandardID == &DeadMachineInstructionElimID)
2850b57cec5SDimitry Andric     return applyDisable(TargetID, DisableMachineDCE);
2860b57cec5SDimitry Andric 
2870b57cec5SDimitry Andric   if (StandardID == &EarlyIfConverterID)
2880b57cec5SDimitry Andric     return applyDisable(TargetID, DisableEarlyIfConversion);
2890b57cec5SDimitry Andric 
2900b57cec5SDimitry Andric   if (StandardID == &EarlyMachineLICMID)
2910b57cec5SDimitry Andric     return applyDisable(TargetID, DisableMachineLICM);
2920b57cec5SDimitry Andric 
2930b57cec5SDimitry Andric   if (StandardID == &MachineCSEID)
2940b57cec5SDimitry Andric     return applyDisable(TargetID, DisableMachineCSE);
2950b57cec5SDimitry Andric 
2960b57cec5SDimitry Andric   if (StandardID == &MachineLICMID)
2970b57cec5SDimitry Andric     return applyDisable(TargetID, DisablePostRAMachineLICM);
2980b57cec5SDimitry Andric 
2990b57cec5SDimitry Andric   if (StandardID == &MachineSinkingID)
3000b57cec5SDimitry Andric     return applyDisable(TargetID, DisableMachineSink);
3010b57cec5SDimitry Andric 
3020b57cec5SDimitry Andric   if (StandardID == &PostRAMachineSinkingID)
3030b57cec5SDimitry Andric     return applyDisable(TargetID, DisablePostRAMachineSink);
3040b57cec5SDimitry Andric 
3050b57cec5SDimitry Andric   if (StandardID == &MachineCopyPropagationID)
3060b57cec5SDimitry Andric     return applyDisable(TargetID, DisableCopyProp);
3070b57cec5SDimitry Andric 
3080b57cec5SDimitry Andric   return TargetID;
3090b57cec5SDimitry Andric }
3100b57cec5SDimitry Andric 
3110b57cec5SDimitry Andric //===---------------------------------------------------------------------===//
3120b57cec5SDimitry Andric /// TargetPassConfig
3130b57cec5SDimitry Andric //===---------------------------------------------------------------------===//
3140b57cec5SDimitry Andric 
3150b57cec5SDimitry Andric INITIALIZE_PASS(TargetPassConfig, "targetpassconfig",
3160b57cec5SDimitry Andric                 "Target Pass Configuration", false, false)
3170b57cec5SDimitry Andric char TargetPassConfig::ID = 0;
3180b57cec5SDimitry Andric 
3190b57cec5SDimitry Andric namespace {
3200b57cec5SDimitry Andric 
3210b57cec5SDimitry Andric struct InsertedPass {
3220b57cec5SDimitry Andric   AnalysisID TargetPassID;
3230b57cec5SDimitry Andric   IdentifyingPassPtr InsertedPassID;
3240b57cec5SDimitry Andric   bool VerifyAfter;
3250b57cec5SDimitry Andric 
InsertedPass__anonf8be623c0111::InsertedPass3260b57cec5SDimitry Andric   InsertedPass(AnalysisID TargetPassID, IdentifyingPassPtr InsertedPassID,
327af732203SDimitry Andric                bool VerifyAfter)
3280b57cec5SDimitry Andric       : TargetPassID(TargetPassID), InsertedPassID(InsertedPassID),
329af732203SDimitry Andric         VerifyAfter(VerifyAfter) {}
3300b57cec5SDimitry Andric 
getInsertedPass__anonf8be623c0111::InsertedPass3310b57cec5SDimitry Andric   Pass *getInsertedPass() const {
3320b57cec5SDimitry Andric     assert(InsertedPassID.isValid() && "Illegal Pass ID!");
3330b57cec5SDimitry Andric     if (InsertedPassID.isInstance())
3340b57cec5SDimitry Andric       return InsertedPassID.getInstance();
3350b57cec5SDimitry Andric     Pass *NP = Pass::createPass(InsertedPassID.getID());
3360b57cec5SDimitry Andric     assert(NP && "Pass ID not registered");
3370b57cec5SDimitry Andric     return NP;
3380b57cec5SDimitry Andric   }
3390b57cec5SDimitry Andric };
3400b57cec5SDimitry Andric 
3410b57cec5SDimitry Andric } // end anonymous namespace
3420b57cec5SDimitry Andric 
3430b57cec5SDimitry Andric namespace llvm {
3440b57cec5SDimitry Andric 
345*5f7ddb14SDimitry Andric extern cl::opt<bool> EnableFSDiscriminator;
346*5f7ddb14SDimitry Andric 
3470b57cec5SDimitry Andric class PassConfigImpl {
3480b57cec5SDimitry Andric public:
3490b57cec5SDimitry Andric   // List of passes explicitly substituted by this target. Normally this is
3500b57cec5SDimitry Andric   // empty, but it is a convenient way to suppress or replace specific passes
3510b57cec5SDimitry Andric   // that are part of a standard pass pipeline without overridding the entire
3520b57cec5SDimitry Andric   // pipeline. This mechanism allows target options to inherit a standard pass's
3530b57cec5SDimitry Andric   // user interface. For example, a target may disable a standard pass by
3540b57cec5SDimitry Andric   // default by substituting a pass ID of zero, and the user may still enable
3550b57cec5SDimitry Andric   // that standard pass with an explicit command line option.
3560b57cec5SDimitry Andric   DenseMap<AnalysisID,IdentifyingPassPtr> TargetPasses;
3570b57cec5SDimitry Andric 
3580b57cec5SDimitry Andric   /// Store the pairs of <AnalysisID, AnalysisID> of which the second pass
3590b57cec5SDimitry Andric   /// is inserted after each instance of the first one.
3600b57cec5SDimitry Andric   SmallVector<InsertedPass, 4> InsertedPasses;
3610b57cec5SDimitry Andric };
3620b57cec5SDimitry Andric 
3630b57cec5SDimitry Andric } // end namespace llvm
3640b57cec5SDimitry Andric 
3650b57cec5SDimitry Andric // Out of line virtual method.
~TargetPassConfig()3660b57cec5SDimitry Andric TargetPassConfig::~TargetPassConfig() {
3670b57cec5SDimitry Andric   delete Impl;
3680b57cec5SDimitry Andric }
3690b57cec5SDimitry Andric 
getPassInfo(StringRef PassName)3700b57cec5SDimitry Andric static const PassInfo *getPassInfo(StringRef PassName) {
3710b57cec5SDimitry Andric   if (PassName.empty())
3720b57cec5SDimitry Andric     return nullptr;
3730b57cec5SDimitry Andric 
3740b57cec5SDimitry Andric   const PassRegistry &PR = *PassRegistry::getPassRegistry();
3750b57cec5SDimitry Andric   const PassInfo *PI = PR.getPassInfo(PassName);
3760b57cec5SDimitry Andric   if (!PI)
3770b57cec5SDimitry Andric     report_fatal_error(Twine('\"') + Twine(PassName) +
3780b57cec5SDimitry Andric                        Twine("\" pass is not registered."));
3790b57cec5SDimitry Andric   return PI;
3800b57cec5SDimitry Andric }
3810b57cec5SDimitry Andric 
getPassIDFromName(StringRef PassName)3820b57cec5SDimitry Andric static AnalysisID getPassIDFromName(StringRef PassName) {
3830b57cec5SDimitry Andric   const PassInfo *PI = getPassInfo(PassName);
3840b57cec5SDimitry Andric   return PI ? PI->getTypeInfo() : nullptr;
3850b57cec5SDimitry Andric }
3860b57cec5SDimitry Andric 
3870b57cec5SDimitry Andric static std::pair<StringRef, unsigned>
getPassNameAndInstanceNum(StringRef PassName)3880b57cec5SDimitry Andric getPassNameAndInstanceNum(StringRef PassName) {
3890b57cec5SDimitry Andric   StringRef Name, InstanceNumStr;
3900b57cec5SDimitry Andric   std::tie(Name, InstanceNumStr) = PassName.split(',');
3910b57cec5SDimitry Andric 
3920b57cec5SDimitry Andric   unsigned InstanceNum = 0;
3930b57cec5SDimitry Andric   if (!InstanceNumStr.empty() && InstanceNumStr.getAsInteger(10, InstanceNum))
3940b57cec5SDimitry Andric     report_fatal_error("invalid pass instance specifier " + PassName);
3950b57cec5SDimitry Andric 
3960b57cec5SDimitry Andric   return std::make_pair(Name, InstanceNum);
3970b57cec5SDimitry Andric }
3980b57cec5SDimitry Andric 
setStartStopPasses()3990b57cec5SDimitry Andric void TargetPassConfig::setStartStopPasses() {
4000b57cec5SDimitry Andric   StringRef StartBeforeName;
4010b57cec5SDimitry Andric   std::tie(StartBeforeName, StartBeforeInstanceNum) =
4020b57cec5SDimitry Andric     getPassNameAndInstanceNum(StartBeforeOpt);
4030b57cec5SDimitry Andric 
4040b57cec5SDimitry Andric   StringRef StartAfterName;
4050b57cec5SDimitry Andric   std::tie(StartAfterName, StartAfterInstanceNum) =
4060b57cec5SDimitry Andric     getPassNameAndInstanceNum(StartAfterOpt);
4070b57cec5SDimitry Andric 
4080b57cec5SDimitry Andric   StringRef StopBeforeName;
4090b57cec5SDimitry Andric   std::tie(StopBeforeName, StopBeforeInstanceNum)
4100b57cec5SDimitry Andric     = getPassNameAndInstanceNum(StopBeforeOpt);
4110b57cec5SDimitry Andric 
4120b57cec5SDimitry Andric   StringRef StopAfterName;
4130b57cec5SDimitry Andric   std::tie(StopAfterName, StopAfterInstanceNum)
4140b57cec5SDimitry Andric     = getPassNameAndInstanceNum(StopAfterOpt);
4150b57cec5SDimitry Andric 
4160b57cec5SDimitry Andric   StartBefore = getPassIDFromName(StartBeforeName);
4170b57cec5SDimitry Andric   StartAfter = getPassIDFromName(StartAfterName);
4180b57cec5SDimitry Andric   StopBefore = getPassIDFromName(StopBeforeName);
4190b57cec5SDimitry Andric   StopAfter = getPassIDFromName(StopAfterName);
4200b57cec5SDimitry Andric   if (StartBefore && StartAfter)
4210b57cec5SDimitry Andric     report_fatal_error(Twine(StartBeforeOptName) + Twine(" and ") +
4220b57cec5SDimitry Andric                        Twine(StartAfterOptName) + Twine(" specified!"));
4230b57cec5SDimitry Andric   if (StopBefore && StopAfter)
4240b57cec5SDimitry Andric     report_fatal_error(Twine(StopBeforeOptName) + Twine(" and ") +
4250b57cec5SDimitry Andric                        Twine(StopAfterOptName) + Twine(" specified!"));
4260b57cec5SDimitry Andric   Started = (StartAfter == nullptr) && (StartBefore == nullptr);
4270b57cec5SDimitry Andric }
4280b57cec5SDimitry Andric 
getCGPassBuilderOption()429af732203SDimitry Andric CGPassBuilderOption llvm::getCGPassBuilderOption() {
430af732203SDimitry Andric   CGPassBuilderOption Opt;
431af732203SDimitry Andric 
432af732203SDimitry Andric #define SET_OPTION(Option)                                                     \
433af732203SDimitry Andric   if (Option.getNumOccurrences())                                              \
434af732203SDimitry Andric     Opt.Option = Option;
435af732203SDimitry Andric 
436af732203SDimitry Andric   SET_OPTION(EnableFastISelOption)
437af732203SDimitry Andric   SET_OPTION(EnableGlobalISelAbort)
438af732203SDimitry Andric   SET_OPTION(EnableGlobalISelOption)
439af732203SDimitry Andric   SET_OPTION(EnableIPRA)
440af732203SDimitry Andric   SET_OPTION(OptimizeRegAlloc)
441af732203SDimitry Andric   SET_OPTION(VerifyMachineCode)
442af732203SDimitry Andric 
443af732203SDimitry Andric #define SET_BOOLEAN_OPTION(Option) Opt.Option = Option;
444af732203SDimitry Andric 
445af732203SDimitry Andric   SET_BOOLEAN_OPTION(EarlyLiveIntervals)
446af732203SDimitry Andric   SET_BOOLEAN_OPTION(EnableBlockPlacementStats)
447af732203SDimitry Andric   SET_BOOLEAN_OPTION(EnableImplicitNullChecks)
448af732203SDimitry Andric   SET_BOOLEAN_OPTION(EnableMachineOutliner)
449af732203SDimitry Andric   SET_BOOLEAN_OPTION(MISchedPostRA)
450af732203SDimitry Andric   SET_BOOLEAN_OPTION(UseCFLAA)
451af732203SDimitry Andric   SET_BOOLEAN_OPTION(DisableMergeICmps)
452af732203SDimitry Andric   SET_BOOLEAN_OPTION(DisableLSR)
453af732203SDimitry Andric   SET_BOOLEAN_OPTION(DisableConstantHoisting)
454af732203SDimitry Andric   SET_BOOLEAN_OPTION(DisableCGP)
455af732203SDimitry Andric   SET_BOOLEAN_OPTION(DisablePartialLibcallInlining)
456af732203SDimitry Andric   SET_BOOLEAN_OPTION(PrintLSR)
457af732203SDimitry Andric   SET_BOOLEAN_OPTION(PrintISelInput)
458af732203SDimitry Andric   SET_BOOLEAN_OPTION(PrintGCInfo)
459af732203SDimitry Andric 
460af732203SDimitry Andric   return Opt;
461af732203SDimitry Andric }
462af732203SDimitry Andric 
registerPartialPipelineCallback(PassInstrumentationCallbacks & PIC,LLVMTargetMachine & LLVMTM)463af732203SDimitry Andric static void registerPartialPipelineCallback(PassInstrumentationCallbacks &PIC,
464af732203SDimitry Andric                                             LLVMTargetMachine &LLVMTM) {
465af732203SDimitry Andric   StringRef StartBefore;
466af732203SDimitry Andric   StringRef StartAfter;
467af732203SDimitry Andric   StringRef StopBefore;
468af732203SDimitry Andric   StringRef StopAfter;
469af732203SDimitry Andric 
470af732203SDimitry Andric   unsigned StartBeforeInstanceNum = 0;
471af732203SDimitry Andric   unsigned StartAfterInstanceNum = 0;
472af732203SDimitry Andric   unsigned StopBeforeInstanceNum = 0;
473af732203SDimitry Andric   unsigned StopAfterInstanceNum = 0;
474af732203SDimitry Andric 
475af732203SDimitry Andric   std::tie(StartBefore, StartBeforeInstanceNum) =
476af732203SDimitry Andric       getPassNameAndInstanceNum(StartBeforeOpt);
477af732203SDimitry Andric   std::tie(StartAfter, StartAfterInstanceNum) =
478af732203SDimitry Andric       getPassNameAndInstanceNum(StartAfterOpt);
479af732203SDimitry Andric   std::tie(StopBefore, StopBeforeInstanceNum) =
480af732203SDimitry Andric       getPassNameAndInstanceNum(StopBeforeOpt);
481af732203SDimitry Andric   std::tie(StopAfter, StopAfterInstanceNum) =
482af732203SDimitry Andric       getPassNameAndInstanceNum(StopAfterOpt);
483af732203SDimitry Andric 
484af732203SDimitry Andric   if (StartBefore.empty() && StartAfter.empty() && StopBefore.empty() &&
485af732203SDimitry Andric       StopAfter.empty())
486af732203SDimitry Andric     return;
487af732203SDimitry Andric 
488af732203SDimitry Andric   std::tie(StartBefore, std::ignore) =
489af732203SDimitry Andric       LLVMTM.getPassNameFromLegacyName(StartBefore);
490af732203SDimitry Andric   std::tie(StartAfter, std::ignore) =
491af732203SDimitry Andric       LLVMTM.getPassNameFromLegacyName(StartAfter);
492af732203SDimitry Andric   std::tie(StopBefore, std::ignore) =
493af732203SDimitry Andric       LLVMTM.getPassNameFromLegacyName(StopBefore);
494af732203SDimitry Andric   std::tie(StopAfter, std::ignore) =
495af732203SDimitry Andric       LLVMTM.getPassNameFromLegacyName(StopAfter);
496af732203SDimitry Andric   if (!StartBefore.empty() && !StartAfter.empty())
497af732203SDimitry Andric     report_fatal_error(Twine(StartBeforeOptName) + Twine(" and ") +
498af732203SDimitry Andric                        Twine(StartAfterOptName) + Twine(" specified!"));
499af732203SDimitry Andric   if (!StopBefore.empty() && !StopAfter.empty())
500af732203SDimitry Andric     report_fatal_error(Twine(StopBeforeOptName) + Twine(" and ") +
501af732203SDimitry Andric                        Twine(StopAfterOptName) + Twine(" specified!"));
502af732203SDimitry Andric 
503af732203SDimitry Andric   PIC.registerShouldRunOptionalPassCallback(
504af732203SDimitry Andric       [=, EnableCurrent = StartBefore.empty() && StartAfter.empty(),
505af732203SDimitry Andric        EnableNext = Optional<bool>(), StartBeforeCount = 0u,
506af732203SDimitry Andric        StartAfterCount = 0u, StopBeforeCount = 0u,
507af732203SDimitry Andric        StopAfterCount = 0u](StringRef P, Any) mutable {
508af732203SDimitry Andric         bool StartBeforePass = !StartBefore.empty() && P.contains(StartBefore);
509af732203SDimitry Andric         bool StartAfterPass = !StartAfter.empty() && P.contains(StartAfter);
510af732203SDimitry Andric         bool StopBeforePass = !StopBefore.empty() && P.contains(StopBefore);
511af732203SDimitry Andric         bool StopAfterPass = !StopAfter.empty() && P.contains(StopAfter);
512af732203SDimitry Andric 
513af732203SDimitry Andric         // Implement -start-after/-stop-after
514af732203SDimitry Andric         if (EnableNext) {
515af732203SDimitry Andric           EnableCurrent = *EnableNext;
516af732203SDimitry Andric           EnableNext.reset();
517af732203SDimitry Andric         }
518af732203SDimitry Andric 
519af732203SDimitry Andric         // Using PIC.registerAfterPassCallback won't work because if this
520af732203SDimitry Andric         // callback returns false, AfterPassCallback is also skipped.
521af732203SDimitry Andric         if (StartAfterPass && StartAfterCount++ == StartAfterInstanceNum) {
522af732203SDimitry Andric           assert(!EnableNext && "Error: assign to EnableNext more than once");
523af732203SDimitry Andric           EnableNext = true;
524af732203SDimitry Andric         }
525af732203SDimitry Andric         if (StopAfterPass && StopAfterCount++ == StopAfterInstanceNum) {
526af732203SDimitry Andric           assert(!EnableNext && "Error: assign to EnableNext more than once");
527af732203SDimitry Andric           EnableNext = false;
528af732203SDimitry Andric         }
529af732203SDimitry Andric 
530af732203SDimitry Andric         if (StartBeforePass && StartBeforeCount++ == StartBeforeInstanceNum)
531af732203SDimitry Andric           EnableCurrent = true;
532af732203SDimitry Andric         if (StopBeforePass && StopBeforeCount++ == StopBeforeInstanceNum)
533af732203SDimitry Andric           EnableCurrent = false;
534af732203SDimitry Andric         return EnableCurrent;
535af732203SDimitry Andric       });
536af732203SDimitry Andric }
537af732203SDimitry Andric 
registerCodeGenCallback(PassInstrumentationCallbacks & PIC,LLVMTargetMachine & LLVMTM)538af732203SDimitry Andric void llvm::registerCodeGenCallback(PassInstrumentationCallbacks &PIC,
539af732203SDimitry Andric                                    LLVMTargetMachine &LLVMTM) {
540af732203SDimitry Andric 
541af732203SDimitry Andric   // Register a callback for disabling passes.
542af732203SDimitry Andric   PIC.registerShouldRunOptionalPassCallback([](StringRef P, Any) {
543af732203SDimitry Andric 
544af732203SDimitry Andric #define DISABLE_PASS(Option, Name)                                             \
545af732203SDimitry Andric   if (Option && P.contains(#Name))                                             \
546af732203SDimitry Andric     return false;
547af732203SDimitry Andric     DISABLE_PASS(DisableBlockPlacement, MachineBlockPlacementPass)
548af732203SDimitry Andric     DISABLE_PASS(DisableBranchFold, BranchFolderPass)
549af732203SDimitry Andric     DISABLE_PASS(DisableCopyProp, MachineCopyPropagationPass)
550af732203SDimitry Andric     DISABLE_PASS(DisableEarlyIfConversion, EarlyIfConverterPass)
551af732203SDimitry Andric     DISABLE_PASS(DisableEarlyTailDup, EarlyTailDuplicatePass)
552af732203SDimitry Andric     DISABLE_PASS(DisableMachineCSE, MachineCSEPass)
553af732203SDimitry Andric     DISABLE_PASS(DisableMachineDCE, DeadMachineInstructionElimPass)
554af732203SDimitry Andric     DISABLE_PASS(DisableMachineLICM, EarlyMachineLICMPass)
555af732203SDimitry Andric     DISABLE_PASS(DisableMachineSink, MachineSinkingPass)
556af732203SDimitry Andric     DISABLE_PASS(DisablePostRAMachineLICM, MachineLICMPass)
557af732203SDimitry Andric     DISABLE_PASS(DisablePostRAMachineSink, PostRAMachineSinkingPass)
558af732203SDimitry Andric     DISABLE_PASS(DisablePostRASched, PostRASchedulerPass)
559af732203SDimitry Andric     DISABLE_PASS(DisableSSC, StackSlotColoringPass)
560af732203SDimitry Andric     DISABLE_PASS(DisableTailDuplicate, TailDuplicatePass)
561af732203SDimitry Andric 
562af732203SDimitry Andric     return true;
563af732203SDimitry Andric   });
564af732203SDimitry Andric 
565af732203SDimitry Andric   registerPartialPipelineCallback(PIC, LLVMTM);
566af732203SDimitry Andric }
567af732203SDimitry Andric 
5680b57cec5SDimitry Andric // Out of line constructor provides default values for pass options and
5690b57cec5SDimitry Andric // registers all common codegen passes.
TargetPassConfig(LLVMTargetMachine & TM,PassManagerBase & pm)5700b57cec5SDimitry Andric TargetPassConfig::TargetPassConfig(LLVMTargetMachine &TM, PassManagerBase &pm)
5710b57cec5SDimitry Andric     : ImmutablePass(ID), PM(&pm), TM(&TM) {
5720b57cec5SDimitry Andric   Impl = new PassConfigImpl();
5730b57cec5SDimitry Andric 
5740b57cec5SDimitry Andric   // Register all target independent codegen passes to activate their PassIDs,
5750b57cec5SDimitry Andric   // including this pass itself.
5760b57cec5SDimitry Andric   initializeCodeGen(*PassRegistry::getPassRegistry());
5770b57cec5SDimitry Andric 
5780b57cec5SDimitry Andric   // Also register alias analysis passes required by codegen passes.
5790b57cec5SDimitry Andric   initializeBasicAAWrapperPassPass(*PassRegistry::getPassRegistry());
5800b57cec5SDimitry Andric   initializeAAResultsWrapperPassPass(*PassRegistry::getPassRegistry());
5810b57cec5SDimitry Andric 
5820b57cec5SDimitry Andric   if (EnableIPRA.getNumOccurrences())
5830b57cec5SDimitry Andric     TM.Options.EnableIPRA = EnableIPRA;
5840b57cec5SDimitry Andric   else {
5850b57cec5SDimitry Andric     // If not explicitly specified, use target default.
5860b57cec5SDimitry Andric     TM.Options.EnableIPRA |= TM.useIPRA();
5870b57cec5SDimitry Andric   }
5880b57cec5SDimitry Andric 
5890b57cec5SDimitry Andric   if (TM.Options.EnableIPRA)
5900b57cec5SDimitry Andric     setRequiresCodeGenSCCOrder();
5910b57cec5SDimitry Andric 
5920b57cec5SDimitry Andric   if (EnableGlobalISelAbort.getNumOccurrences())
5930b57cec5SDimitry Andric     TM.Options.GlobalISelAbort = EnableGlobalISelAbort;
5940b57cec5SDimitry Andric 
5950b57cec5SDimitry Andric   setStartStopPasses();
5960b57cec5SDimitry Andric }
5970b57cec5SDimitry Andric 
getOptLevel() const5980b57cec5SDimitry Andric CodeGenOpt::Level TargetPassConfig::getOptLevel() const {
5990b57cec5SDimitry Andric   return TM->getOptLevel();
6000b57cec5SDimitry Andric }
6010b57cec5SDimitry Andric 
6020b57cec5SDimitry Andric /// Insert InsertedPassID pass after TargetPassID.
insertPass(AnalysisID TargetPassID,IdentifyingPassPtr InsertedPassID,bool VerifyAfter)6030b57cec5SDimitry Andric void TargetPassConfig::insertPass(AnalysisID TargetPassID,
6040b57cec5SDimitry Andric                                   IdentifyingPassPtr InsertedPassID,
605af732203SDimitry Andric                                   bool VerifyAfter) {
6060b57cec5SDimitry Andric   assert(((!InsertedPassID.isInstance() &&
6070b57cec5SDimitry Andric            TargetPassID != InsertedPassID.getID()) ||
6080b57cec5SDimitry Andric           (InsertedPassID.isInstance() &&
6090b57cec5SDimitry Andric            TargetPassID != InsertedPassID.getInstance()->getPassID())) &&
6100b57cec5SDimitry Andric          "Insert a pass after itself!");
611af732203SDimitry Andric   Impl->InsertedPasses.emplace_back(TargetPassID, InsertedPassID, VerifyAfter);
6120b57cec5SDimitry Andric }
6130b57cec5SDimitry Andric 
6140b57cec5SDimitry Andric /// createPassConfig - Create a pass configuration object to be used by
6150b57cec5SDimitry Andric /// addPassToEmitX methods for generating a pipeline of CodeGen passes.
6160b57cec5SDimitry Andric ///
6170b57cec5SDimitry Andric /// Targets may override this to extend TargetPassConfig.
createPassConfig(PassManagerBase & PM)6180b57cec5SDimitry Andric TargetPassConfig *LLVMTargetMachine::createPassConfig(PassManagerBase &PM) {
6190b57cec5SDimitry Andric   return new TargetPassConfig(*this, PM);
6200b57cec5SDimitry Andric }
6210b57cec5SDimitry Andric 
TargetPassConfig()6220b57cec5SDimitry Andric TargetPassConfig::TargetPassConfig()
6230b57cec5SDimitry Andric   : ImmutablePass(ID) {
6240b57cec5SDimitry Andric   report_fatal_error("Trying to construct TargetPassConfig without a target "
6250b57cec5SDimitry Andric                      "machine. Scheduling a CodeGen pass without a target "
6260b57cec5SDimitry Andric                      "triple set?");
6270b57cec5SDimitry Andric }
6280b57cec5SDimitry Andric 
willCompleteCodeGenPipeline()6290b57cec5SDimitry Andric bool TargetPassConfig::willCompleteCodeGenPipeline() {
6300b57cec5SDimitry Andric   return StopBeforeOpt.empty() && StopAfterOpt.empty();
6310b57cec5SDimitry Andric }
6320b57cec5SDimitry Andric 
hasLimitedCodeGenPipeline()6330b57cec5SDimitry Andric bool TargetPassConfig::hasLimitedCodeGenPipeline() {
6340b57cec5SDimitry Andric   return !StartBeforeOpt.empty() || !StartAfterOpt.empty() ||
6350b57cec5SDimitry Andric          !willCompleteCodeGenPipeline();
6360b57cec5SDimitry Andric }
6370b57cec5SDimitry Andric 
6380b57cec5SDimitry Andric std::string
getLimitedCodeGenPipelineReason(const char * Separator)6395ffd83dbSDimitry Andric TargetPassConfig::getLimitedCodeGenPipelineReason(const char *Separator) {
6400b57cec5SDimitry Andric   if (!hasLimitedCodeGenPipeline())
6410b57cec5SDimitry Andric     return std::string();
6420b57cec5SDimitry Andric   std::string Res;
6430b57cec5SDimitry Andric   static cl::opt<std::string> *PassNames[] = {&StartAfterOpt, &StartBeforeOpt,
6440b57cec5SDimitry Andric                                               &StopAfterOpt, &StopBeforeOpt};
6450b57cec5SDimitry Andric   static const char *OptNames[] = {StartAfterOptName, StartBeforeOptName,
6460b57cec5SDimitry Andric                                    StopAfterOptName, StopBeforeOptName};
6470b57cec5SDimitry Andric   bool IsFirst = true;
6480b57cec5SDimitry Andric   for (int Idx = 0; Idx < 4; ++Idx)
6490b57cec5SDimitry Andric     if (!PassNames[Idx]->empty()) {
6500b57cec5SDimitry Andric       if (!IsFirst)
6510b57cec5SDimitry Andric         Res += Separator;
6520b57cec5SDimitry Andric       IsFirst = false;
6530b57cec5SDimitry Andric       Res += OptNames[Idx];
6540b57cec5SDimitry Andric     }
6550b57cec5SDimitry Andric   return Res;
6560b57cec5SDimitry Andric }
6570b57cec5SDimitry Andric 
6580b57cec5SDimitry Andric // Helper to verify the analysis is really immutable.
setOpt(bool & Opt,bool Val)6590b57cec5SDimitry Andric void TargetPassConfig::setOpt(bool &Opt, bool Val) {
6600b57cec5SDimitry Andric   assert(!Initialized && "PassConfig is immutable");
6610b57cec5SDimitry Andric   Opt = Val;
6620b57cec5SDimitry Andric }
6630b57cec5SDimitry Andric 
substitutePass(AnalysisID StandardID,IdentifyingPassPtr TargetID)6640b57cec5SDimitry Andric void TargetPassConfig::substitutePass(AnalysisID StandardID,
6650b57cec5SDimitry Andric                                       IdentifyingPassPtr TargetID) {
6660b57cec5SDimitry Andric   Impl->TargetPasses[StandardID] = TargetID;
6670b57cec5SDimitry Andric }
6680b57cec5SDimitry Andric 
getPassSubstitution(AnalysisID ID) const6690b57cec5SDimitry Andric IdentifyingPassPtr TargetPassConfig::getPassSubstitution(AnalysisID ID) const {
6700b57cec5SDimitry Andric   DenseMap<AnalysisID, IdentifyingPassPtr>::const_iterator
6710b57cec5SDimitry Andric     I = Impl->TargetPasses.find(ID);
6720b57cec5SDimitry Andric   if (I == Impl->TargetPasses.end())
6730b57cec5SDimitry Andric     return ID;
6740b57cec5SDimitry Andric   return I->second;
6750b57cec5SDimitry Andric }
6760b57cec5SDimitry Andric 
isPassSubstitutedOrOverridden(AnalysisID ID) const6770b57cec5SDimitry Andric bool TargetPassConfig::isPassSubstitutedOrOverridden(AnalysisID ID) const {
6780b57cec5SDimitry Andric   IdentifyingPassPtr TargetID = getPassSubstitution(ID);
6790b57cec5SDimitry Andric   IdentifyingPassPtr FinalPtr = overridePass(ID, TargetID);
6800b57cec5SDimitry Andric   return !FinalPtr.isValid() || FinalPtr.isInstance() ||
6810b57cec5SDimitry Andric       FinalPtr.getID() != ID;
6820b57cec5SDimitry Andric }
6830b57cec5SDimitry Andric 
6840b57cec5SDimitry Andric /// Add a pass to the PassManager if that pass is supposed to be run.  If the
6850b57cec5SDimitry Andric /// Started/Stopped flags indicate either that the compilation should start at
6860b57cec5SDimitry Andric /// a later pass or that it should stop after an earlier pass, then do not add
6870b57cec5SDimitry Andric /// the pass.  Finally, compare the current pass against the StartAfter
6880b57cec5SDimitry Andric /// and StopAfter options and change the Started/Stopped flags accordingly.
addPass(Pass * P,bool verifyAfter)689af732203SDimitry Andric void TargetPassConfig::addPass(Pass *P, bool verifyAfter) {
6900b57cec5SDimitry Andric   assert(!Initialized && "PassConfig is immutable");
6910b57cec5SDimitry Andric 
6920b57cec5SDimitry Andric   // Cache the Pass ID here in case the pass manager finds this pass is
6930b57cec5SDimitry Andric   // redundant with ones already scheduled / available, and deletes it.
6940b57cec5SDimitry Andric   // Fundamentally, once we add the pass to the manager, we no longer own it
6950b57cec5SDimitry Andric   // and shouldn't reference it.
6960b57cec5SDimitry Andric   AnalysisID PassID = P->getPassID();
6970b57cec5SDimitry Andric 
6980b57cec5SDimitry Andric   if (StartBefore == PassID && StartBeforeCount++ == StartBeforeInstanceNum)
6990b57cec5SDimitry Andric     Started = true;
7000b57cec5SDimitry Andric   if (StopBefore == PassID && StopBeforeCount++ == StopBeforeInstanceNum)
7010b57cec5SDimitry Andric     Stopped = true;
7020b57cec5SDimitry Andric   if (Started && !Stopped) {
7035ffd83dbSDimitry Andric     if (AddingMachinePasses)
7045ffd83dbSDimitry Andric       addMachinePrePasses();
7050b57cec5SDimitry Andric     std::string Banner;
7060b57cec5SDimitry Andric     // Construct banner message before PM->add() as that may delete the pass.
707af732203SDimitry Andric     if (AddingMachinePasses && verifyAfter)
7080b57cec5SDimitry Andric       Banner = std::string("After ") + std::string(P->getPassName());
7090b57cec5SDimitry Andric     PM->add(P);
7105ffd83dbSDimitry Andric     if (AddingMachinePasses)
711af732203SDimitry Andric       addMachinePostPasses(Banner, /*AllowVerify*/ verifyAfter);
7120b57cec5SDimitry Andric 
7130b57cec5SDimitry Andric     // Add the passes after the pass P if there is any.
714af732203SDimitry Andric     for (const auto &IP : Impl->InsertedPasses) {
7150b57cec5SDimitry Andric       if (IP.TargetPassID == PassID)
716af732203SDimitry Andric         addPass(IP.getInsertedPass(), IP.VerifyAfter);
7170b57cec5SDimitry Andric     }
7180b57cec5SDimitry Andric   } else {
7190b57cec5SDimitry Andric     delete P;
7200b57cec5SDimitry Andric   }
7210b57cec5SDimitry Andric 
7220b57cec5SDimitry Andric   if (StopAfter == PassID && StopAfterCount++ == StopAfterInstanceNum)
7230b57cec5SDimitry Andric     Stopped = true;
7240b57cec5SDimitry Andric 
7250b57cec5SDimitry Andric   if (StartAfter == PassID && StartAfterCount++ == StartAfterInstanceNum)
7260b57cec5SDimitry Andric     Started = true;
7270b57cec5SDimitry Andric   if (Stopped && !Started)
7280b57cec5SDimitry Andric     report_fatal_error("Cannot stop compilation after pass that is not run");
7290b57cec5SDimitry Andric }
7300b57cec5SDimitry Andric 
7310b57cec5SDimitry Andric /// Add a CodeGen pass at this point in the pipeline after checking for target
7320b57cec5SDimitry Andric /// and command line overrides.
7330b57cec5SDimitry Andric ///
7340b57cec5SDimitry Andric /// addPass cannot return a pointer to the pass instance because is internal the
7350b57cec5SDimitry Andric /// PassManager and the instance we create here may already be freed.
addPass(AnalysisID PassID,bool verifyAfter)736af732203SDimitry Andric AnalysisID TargetPassConfig::addPass(AnalysisID PassID, bool verifyAfter) {
7370b57cec5SDimitry Andric   IdentifyingPassPtr TargetID = getPassSubstitution(PassID);
7380b57cec5SDimitry Andric   IdentifyingPassPtr FinalPtr = overridePass(PassID, TargetID);
7390b57cec5SDimitry Andric   if (!FinalPtr.isValid())
7400b57cec5SDimitry Andric     return nullptr;
7410b57cec5SDimitry Andric 
7420b57cec5SDimitry Andric   Pass *P;
7430b57cec5SDimitry Andric   if (FinalPtr.isInstance())
7440b57cec5SDimitry Andric     P = FinalPtr.getInstance();
7450b57cec5SDimitry Andric   else {
7460b57cec5SDimitry Andric     P = Pass::createPass(FinalPtr.getID());
7470b57cec5SDimitry Andric     if (!P)
7480b57cec5SDimitry Andric       llvm_unreachable("Pass ID not registered");
7490b57cec5SDimitry Andric   }
7500b57cec5SDimitry Andric   AnalysisID FinalID = P->getPassID();
751af732203SDimitry Andric   addPass(P, verifyAfter); // Ends the lifetime of P.
7520b57cec5SDimitry Andric 
7530b57cec5SDimitry Andric   return FinalID;
7540b57cec5SDimitry Andric }
7550b57cec5SDimitry Andric 
printAndVerify(const std::string & Banner)7560b57cec5SDimitry Andric void TargetPassConfig::printAndVerify(const std::string &Banner) {
7570b57cec5SDimitry Andric   addPrintPass(Banner);
7580b57cec5SDimitry Andric   addVerifyPass(Banner);
7590b57cec5SDimitry Andric }
7600b57cec5SDimitry Andric 
addPrintPass(const std::string & Banner)7610b57cec5SDimitry Andric void TargetPassConfig::addPrintPass(const std::string &Banner) {
762af732203SDimitry Andric   if (PrintAfterISel)
7630b57cec5SDimitry Andric     PM->add(createMachineFunctionPrinterPass(dbgs(), Banner));
7640b57cec5SDimitry Andric }
7650b57cec5SDimitry Andric 
addVerifyPass(const std::string & Banner)7660b57cec5SDimitry Andric void TargetPassConfig::addVerifyPass(const std::string &Banner) {
7670b57cec5SDimitry Andric   bool Verify = VerifyMachineCode == cl::BOU_TRUE;
7680b57cec5SDimitry Andric #ifdef EXPENSIVE_CHECKS
7690b57cec5SDimitry Andric   if (VerifyMachineCode == cl::BOU_UNSET)
7700b57cec5SDimitry Andric     Verify = TM->isMachineVerifierClean();
7710b57cec5SDimitry Andric #endif
7720b57cec5SDimitry Andric   if (Verify)
7730b57cec5SDimitry Andric     PM->add(createMachineVerifierPass(Banner));
7740b57cec5SDimitry Andric }
7750b57cec5SDimitry Andric 
addDebugifyPass()7765ffd83dbSDimitry Andric void TargetPassConfig::addDebugifyPass() {
7775ffd83dbSDimitry Andric   PM->add(createDebugifyMachineModulePass());
7785ffd83dbSDimitry Andric }
7795ffd83dbSDimitry Andric 
addStripDebugPass()7805ffd83dbSDimitry Andric void TargetPassConfig::addStripDebugPass() {
7815ffd83dbSDimitry Andric   PM->add(createStripDebugMachineModulePass(/*OnlyDebugified=*/true));
7825ffd83dbSDimitry Andric }
7835ffd83dbSDimitry Andric 
addCheckDebugPass()784af732203SDimitry Andric void TargetPassConfig::addCheckDebugPass() {
785af732203SDimitry Andric   PM->add(createCheckDebugMachineModulePass());
786af732203SDimitry Andric }
787af732203SDimitry Andric 
addMachinePrePasses(bool AllowDebugify)7885ffd83dbSDimitry Andric void TargetPassConfig::addMachinePrePasses(bool AllowDebugify) {
789af732203SDimitry Andric   if (AllowDebugify && DebugifyIsSafe &&
790af732203SDimitry Andric       (DebugifyAndStripAll == cl::BOU_TRUE ||
791af732203SDimitry Andric        DebugifyCheckAndStripAll == cl::BOU_TRUE))
7925ffd83dbSDimitry Andric     addDebugifyPass();
7935ffd83dbSDimitry Andric }
7945ffd83dbSDimitry Andric 
addMachinePostPasses(const std::string & Banner,bool AllowVerify,bool AllowStrip)7955ffd83dbSDimitry Andric void TargetPassConfig::addMachinePostPasses(const std::string &Banner,
796af732203SDimitry Andric                                             bool AllowVerify, bool AllowStrip) {
797af732203SDimitry Andric   if (DebugifyIsSafe) {
798af732203SDimitry Andric     if (DebugifyCheckAndStripAll == cl::BOU_TRUE) {
799af732203SDimitry Andric       addCheckDebugPass();
8005ffd83dbSDimitry Andric       addStripDebugPass();
801af732203SDimitry Andric     } else if (DebugifyAndStripAll == cl::BOU_TRUE)
802af732203SDimitry Andric       addStripDebugPass();
803af732203SDimitry Andric   }
8045ffd83dbSDimitry Andric   if (AllowVerify)
8055ffd83dbSDimitry Andric     addVerifyPass(Banner);
8065ffd83dbSDimitry Andric }
8075ffd83dbSDimitry Andric 
8080b57cec5SDimitry Andric /// Add common target configurable passes that perform LLVM IR to IR transforms
8090b57cec5SDimitry Andric /// following machine independent optimization.
addIRPasses()8100b57cec5SDimitry Andric void TargetPassConfig::addIRPasses() {
8115ffd83dbSDimitry Andric   // Before running any passes, run the verifier to determine if the input
8125ffd83dbSDimitry Andric   // coming from the front-end and/or optimizer is valid.
8135ffd83dbSDimitry Andric   if (!DisableVerify)
8145ffd83dbSDimitry Andric     addPass(createVerifierPass());
8155ffd83dbSDimitry Andric 
8165ffd83dbSDimitry Andric   if (getOptLevel() != CodeGenOpt::None) {
8170b57cec5SDimitry Andric     switch (UseCFLAA) {
8180b57cec5SDimitry Andric     case CFLAAType::Steensgaard:
8190b57cec5SDimitry Andric       addPass(createCFLSteensAAWrapperPass());
8200b57cec5SDimitry Andric       break;
8210b57cec5SDimitry Andric     case CFLAAType::Andersen:
8220b57cec5SDimitry Andric       addPass(createCFLAndersAAWrapperPass());
8230b57cec5SDimitry Andric       break;
8240b57cec5SDimitry Andric     case CFLAAType::Both:
8250b57cec5SDimitry Andric       addPass(createCFLAndersAAWrapperPass());
8260b57cec5SDimitry Andric       addPass(createCFLSteensAAWrapperPass());
8270b57cec5SDimitry Andric       break;
8280b57cec5SDimitry Andric     default:
8290b57cec5SDimitry Andric       break;
8300b57cec5SDimitry Andric     }
8310b57cec5SDimitry Andric 
8320b57cec5SDimitry Andric     // Basic AliasAnalysis support.
8330b57cec5SDimitry Andric     // Add TypeBasedAliasAnalysis before BasicAliasAnalysis so that
8340b57cec5SDimitry Andric     // BasicAliasAnalysis wins if they disagree. This is intended to help
8350b57cec5SDimitry Andric     // support "obvious" type-punning idioms.
8360b57cec5SDimitry Andric     addPass(createTypeBasedAAWrapperPass());
8370b57cec5SDimitry Andric     addPass(createScopedNoAliasAAWrapperPass());
8380b57cec5SDimitry Andric     addPass(createBasicAAWrapperPass());
8390b57cec5SDimitry Andric 
8400b57cec5SDimitry Andric     // Run loop strength reduction before anything else.
8415ffd83dbSDimitry Andric     if (!DisableLSR) {
8425ffd83dbSDimitry Andric       addPass(createCanonicalizeFreezeInLoopsPass());
8430b57cec5SDimitry Andric       addPass(createLoopStrengthReducePass());
8440b57cec5SDimitry Andric       if (PrintLSR)
8455ffd83dbSDimitry Andric         addPass(createPrintFunctionPass(dbgs(),
8465ffd83dbSDimitry Andric                                         "\n\n*** Code after LSR ***\n"));
8470b57cec5SDimitry Andric     }
8480b57cec5SDimitry Andric 
8490b57cec5SDimitry Andric     // The MergeICmpsPass tries to create memcmp calls by grouping sequences of
8500b57cec5SDimitry Andric     // loads and compares. ExpandMemCmpPass then tries to expand those calls
8510b57cec5SDimitry Andric     // into optimally-sized loads and compares. The transforms are enabled by a
8520b57cec5SDimitry Andric     // target lowering hook.
8530b57cec5SDimitry Andric     if (!DisableMergeICmps)
8540b57cec5SDimitry Andric       addPass(createMergeICmpsLegacyPass());
8550b57cec5SDimitry Andric     addPass(createExpandMemCmpPass());
8560b57cec5SDimitry Andric   }
8570b57cec5SDimitry Andric 
8580b57cec5SDimitry Andric   // Run GC lowering passes for builtin collectors
8590b57cec5SDimitry Andric   // TODO: add a pass insertion point here
860*5f7ddb14SDimitry Andric   addPass(&GCLoweringID);
861*5f7ddb14SDimitry Andric   addPass(&ShadowStackGCLoweringID);
8628bcb0991SDimitry Andric   addPass(createLowerConstantIntrinsicsPass());
8630b57cec5SDimitry Andric 
8640b57cec5SDimitry Andric   // Make sure that no unreachable blocks are instruction selected.
8650b57cec5SDimitry Andric   addPass(createUnreachableBlockEliminationPass());
8660b57cec5SDimitry Andric 
8670b57cec5SDimitry Andric   // Prepare expensive constants for SelectionDAG.
8680b57cec5SDimitry Andric   if (getOptLevel() != CodeGenOpt::None && !DisableConstantHoisting)
8690b57cec5SDimitry Andric     addPass(createConstantHoistingPass());
8700b57cec5SDimitry Andric 
871*5f7ddb14SDimitry Andric   if (getOptLevel() != CodeGenOpt::None)
872*5f7ddb14SDimitry Andric     addPass(createReplaceWithVeclibLegacyPass());
873*5f7ddb14SDimitry Andric 
8740b57cec5SDimitry Andric   if (getOptLevel() != CodeGenOpt::None && !DisablePartialLibcallInlining)
8750b57cec5SDimitry Andric     addPass(createPartiallyInlineLibCallsPass());
8760b57cec5SDimitry Andric 
877*5f7ddb14SDimitry Andric   // Expand vector predication intrinsics into standard IR instructions.
878*5f7ddb14SDimitry Andric   // This pass has to run before ScalarizeMaskedMemIntrin and ExpandReduction
879*5f7ddb14SDimitry Andric   // passes since it emits those kinds of intrinsics.
880*5f7ddb14SDimitry Andric   addPass(createExpandVectorPredicationPass());
8810b57cec5SDimitry Andric 
8820b57cec5SDimitry Andric   // Add scalarization of target's unsupported masked memory intrinsics pass.
8830b57cec5SDimitry Andric   // the unsupported intrinsic will be replaced with a chain of basic blocks,
8840b57cec5SDimitry Andric   // that stores/loads element one-by-one if the appropriate mask bit is set.
885af732203SDimitry Andric   addPass(createScalarizeMaskedMemIntrinLegacyPass());
8860b57cec5SDimitry Andric 
8870b57cec5SDimitry Andric   // Expand reduction intrinsics into shuffle sequences if the target wants to.
888af732203SDimitry Andric   // Allow disabling it for testing purposes.
889af732203SDimitry Andric   if (!DisableExpandReductions)
8900b57cec5SDimitry Andric     addPass(createExpandReductionsPass());
8910b57cec5SDimitry Andric }
8920b57cec5SDimitry Andric 
8930b57cec5SDimitry Andric /// Turn exception handling constructs into something the code generators can
8940b57cec5SDimitry Andric /// handle.
addPassesToHandleExceptions()8950b57cec5SDimitry Andric void TargetPassConfig::addPassesToHandleExceptions() {
8960b57cec5SDimitry Andric   const MCAsmInfo *MCAI = TM->getMCAsmInfo();
8970b57cec5SDimitry Andric   assert(MCAI && "No MCAsmInfo");
8980b57cec5SDimitry Andric   switch (MCAI->getExceptionHandlingType()) {
8990b57cec5SDimitry Andric   case ExceptionHandling::SjLj:
9000b57cec5SDimitry Andric     // SjLj piggy-backs on dwarf for this bit. The cleanups done apply to both
9010b57cec5SDimitry Andric     // Dwarf EH prepare needs to be run after SjLj prepare. Otherwise,
9020b57cec5SDimitry Andric     // catch info can get misplaced when a selector ends up more than one block
9030b57cec5SDimitry Andric     // removed from the parent invoke(s). This could happen when a landing
9040b57cec5SDimitry Andric     // pad is shared by multiple invokes and is also a target of a normal
9050b57cec5SDimitry Andric     // edge from elsewhere.
9065ffd83dbSDimitry Andric     addPass(createSjLjEHPreparePass(TM));
9070b57cec5SDimitry Andric     LLVM_FALLTHROUGH;
9080b57cec5SDimitry Andric   case ExceptionHandling::DwarfCFI:
9090b57cec5SDimitry Andric   case ExceptionHandling::ARM:
910af732203SDimitry Andric   case ExceptionHandling::AIX:
9115ffd83dbSDimitry Andric     addPass(createDwarfEHPass(getOptLevel()));
9120b57cec5SDimitry Andric     break;
9130b57cec5SDimitry Andric   case ExceptionHandling::WinEH:
9140b57cec5SDimitry Andric     // We support using both GCC-style and MSVC-style exceptions on Windows, so
9150b57cec5SDimitry Andric     // add both preparation passes. Each pass will only actually run if it
9160b57cec5SDimitry Andric     // recognizes the personality function.
9170b57cec5SDimitry Andric     addPass(createWinEHPass());
9185ffd83dbSDimitry Andric     addPass(createDwarfEHPass(getOptLevel()));
9190b57cec5SDimitry Andric     break;
9200b57cec5SDimitry Andric   case ExceptionHandling::Wasm:
9210b57cec5SDimitry Andric     // Wasm EH uses Windows EH instructions, but it does not need to demote PHIs
9220b57cec5SDimitry Andric     // on catchpads and cleanuppads because it does not outline them into
9230b57cec5SDimitry Andric     // funclets. Catchswitch blocks are not lowered in SelectionDAG, so we
9240b57cec5SDimitry Andric     // should remove PHIs there.
9250b57cec5SDimitry Andric     addPass(createWinEHPass(/*DemoteCatchSwitchPHIOnly=*/false));
9260b57cec5SDimitry Andric     addPass(createWasmEHPass());
9270b57cec5SDimitry Andric     break;
9280b57cec5SDimitry Andric   case ExceptionHandling::None:
9290b57cec5SDimitry Andric     addPass(createLowerInvokePass());
9300b57cec5SDimitry Andric 
9310b57cec5SDimitry Andric     // The lower invoke pass may create unreachable code. Remove it.
9320b57cec5SDimitry Andric     addPass(createUnreachableBlockEliminationPass());
9330b57cec5SDimitry Andric     break;
9340b57cec5SDimitry Andric   }
9350b57cec5SDimitry Andric }
9360b57cec5SDimitry Andric 
9370b57cec5SDimitry Andric /// Add pass to prepare the LLVM IR for code generation. This should be done
9380b57cec5SDimitry Andric /// before exception handling preparation passes.
addCodeGenPrepare()9390b57cec5SDimitry Andric void TargetPassConfig::addCodeGenPrepare() {
9400b57cec5SDimitry Andric   if (getOptLevel() != CodeGenOpt::None && !DisableCGP)
9410b57cec5SDimitry Andric     addPass(createCodeGenPreparePass());
9420b57cec5SDimitry Andric }
9430b57cec5SDimitry Andric 
9440b57cec5SDimitry Andric /// Add common passes that perform LLVM IR to IR transforms in preparation for
9450b57cec5SDimitry Andric /// instruction selection.
addISelPrepare()9460b57cec5SDimitry Andric void TargetPassConfig::addISelPrepare() {
9470b57cec5SDimitry Andric   addPreISel();
9480b57cec5SDimitry Andric 
9490b57cec5SDimitry Andric   // Force codegen to run according to the callgraph.
9500b57cec5SDimitry Andric   if (requiresCodeGenSCCOrder())
9510b57cec5SDimitry Andric     addPass(new DummyCGSCCPass);
9520b57cec5SDimitry Andric 
9530b57cec5SDimitry Andric   // Add both the safe stack and the stack protection passes: each of them will
9540b57cec5SDimitry Andric   // only protect functions that have corresponding attributes.
9550b57cec5SDimitry Andric   addPass(createSafeStackPass());
9560b57cec5SDimitry Andric   addPass(createStackProtectorPass());
9570b57cec5SDimitry Andric 
9580b57cec5SDimitry Andric   if (PrintISelInput)
9590b57cec5SDimitry Andric     addPass(createPrintFunctionPass(
9600b57cec5SDimitry Andric         dbgs(), "\n\n*** Final LLVM Code input to ISel ***\n"));
9610b57cec5SDimitry Andric 
9620b57cec5SDimitry Andric   // All passes which modify the LLVM IR are now complete; run the verifier
9630b57cec5SDimitry Andric   // to ensure that the IR is valid.
9640b57cec5SDimitry Andric   if (!DisableVerify)
9650b57cec5SDimitry Andric     addPass(createVerifierPass());
9660b57cec5SDimitry Andric }
9670b57cec5SDimitry Andric 
addCoreISelPasses()9680b57cec5SDimitry Andric bool TargetPassConfig::addCoreISelPasses() {
9690b57cec5SDimitry Andric   // Enable FastISel with -fast-isel, but allow that to be overridden.
9700b57cec5SDimitry Andric   TM->setO0WantsFastISel(EnableFastISelOption != cl::BOU_FALSE);
9710b57cec5SDimitry Andric 
9720b57cec5SDimitry Andric   // Determine an instruction selector.
9730b57cec5SDimitry Andric   enum class SelectorType { SelectionDAG, FastISel, GlobalISel };
9740b57cec5SDimitry Andric   SelectorType Selector;
9750b57cec5SDimitry Andric 
9760b57cec5SDimitry Andric   if (EnableFastISelOption == cl::BOU_TRUE)
9770b57cec5SDimitry Andric     Selector = SelectorType::FastISel;
9780b57cec5SDimitry Andric   else if (EnableGlobalISelOption == cl::BOU_TRUE ||
9790b57cec5SDimitry Andric            (TM->Options.EnableGlobalISel &&
9800b57cec5SDimitry Andric             EnableGlobalISelOption != cl::BOU_FALSE))
9810b57cec5SDimitry Andric     Selector = SelectorType::GlobalISel;
9820b57cec5SDimitry Andric   else if (TM->getOptLevel() == CodeGenOpt::None && TM->getO0WantsFastISel())
9830b57cec5SDimitry Andric     Selector = SelectorType::FastISel;
9840b57cec5SDimitry Andric   else
9850b57cec5SDimitry Andric     Selector = SelectorType::SelectionDAG;
9860b57cec5SDimitry Andric 
9870b57cec5SDimitry Andric   // Set consistently TM->Options.EnableFastISel and EnableGlobalISel.
9880b57cec5SDimitry Andric   if (Selector == SelectorType::FastISel) {
9890b57cec5SDimitry Andric     TM->setFastISel(true);
9900b57cec5SDimitry Andric     TM->setGlobalISel(false);
9910b57cec5SDimitry Andric   } else if (Selector == SelectorType::GlobalISel) {
9920b57cec5SDimitry Andric     TM->setFastISel(false);
9930b57cec5SDimitry Andric     TM->setGlobalISel(true);
9940b57cec5SDimitry Andric   }
9950b57cec5SDimitry Andric 
9965ffd83dbSDimitry Andric   // FIXME: Injecting into the DAGISel pipeline seems to cause issues with
9975ffd83dbSDimitry Andric   //        analyses needing to be re-run. This can result in being unable to
9985ffd83dbSDimitry Andric   //        schedule passes (particularly with 'Function Alias Analysis
9995ffd83dbSDimitry Andric   //        Results'). It's not entirely clear why but AFAICT this seems to be
10005ffd83dbSDimitry Andric   //        due to one FunctionPassManager not being able to use analyses from a
10015ffd83dbSDimitry Andric   //        previous one. As we're injecting a ModulePass we break the usual
10025ffd83dbSDimitry Andric   //        pass manager into two. GlobalISel with the fallback path disabled
10035ffd83dbSDimitry Andric   //        and -run-pass seem to be unaffected. The majority of GlobalISel
10045ffd83dbSDimitry Andric   //        testing uses -run-pass so this probably isn't too bad.
10055ffd83dbSDimitry Andric   SaveAndRestore<bool> SavedDebugifyIsSafe(DebugifyIsSafe);
10065ffd83dbSDimitry Andric   if (Selector != SelectorType::GlobalISel || !isGlobalISelAbortEnabled())
10075ffd83dbSDimitry Andric     DebugifyIsSafe = false;
10085ffd83dbSDimitry Andric 
10090b57cec5SDimitry Andric   // Add instruction selector passes.
10100b57cec5SDimitry Andric   if (Selector == SelectorType::GlobalISel) {
10110b57cec5SDimitry Andric     SaveAndRestore<bool> SavedAddingMachinePasses(AddingMachinePasses, true);
10120b57cec5SDimitry Andric     if (addIRTranslator())
10130b57cec5SDimitry Andric       return true;
10140b57cec5SDimitry Andric 
10150b57cec5SDimitry Andric     addPreLegalizeMachineIR();
10160b57cec5SDimitry Andric 
10170b57cec5SDimitry Andric     if (addLegalizeMachineIR())
10180b57cec5SDimitry Andric       return true;
10190b57cec5SDimitry Andric 
10200b57cec5SDimitry Andric     // Before running the register bank selector, ask the target if it
10210b57cec5SDimitry Andric     // wants to run some passes.
10220b57cec5SDimitry Andric     addPreRegBankSelect();
10230b57cec5SDimitry Andric 
10240b57cec5SDimitry Andric     if (addRegBankSelect())
10250b57cec5SDimitry Andric       return true;
10260b57cec5SDimitry Andric 
10270b57cec5SDimitry Andric     addPreGlobalInstructionSelect();
10280b57cec5SDimitry Andric 
10290b57cec5SDimitry Andric     if (addGlobalInstructionSelect())
10300b57cec5SDimitry Andric       return true;
10310b57cec5SDimitry Andric 
10320b57cec5SDimitry Andric     // Pass to reset the MachineFunction if the ISel failed.
10330b57cec5SDimitry Andric     addPass(createResetMachineFunctionPass(
10340b57cec5SDimitry Andric         reportDiagnosticWhenGlobalISelFallback(), isGlobalISelAbortEnabled()));
10350b57cec5SDimitry Andric 
10360b57cec5SDimitry Andric     // Provide a fallback path when we do not want to abort on
10370b57cec5SDimitry Andric     // not-yet-supported input.
10380b57cec5SDimitry Andric     if (!isGlobalISelAbortEnabled() && addInstSelector())
10390b57cec5SDimitry Andric       return true;
10400b57cec5SDimitry Andric 
10410b57cec5SDimitry Andric   } else if (addInstSelector())
10420b57cec5SDimitry Andric     return true;
10430b57cec5SDimitry Andric 
10440b57cec5SDimitry Andric   // Expand pseudo-instructions emitted by ISel. Don't run the verifier before
10450b57cec5SDimitry Andric   // FinalizeISel.
10460b57cec5SDimitry Andric   addPass(&FinalizeISelID);
10470b57cec5SDimitry Andric 
10480b57cec5SDimitry Andric   // Print the instruction selected machine code...
10490b57cec5SDimitry Andric   printAndVerify("After Instruction Selection");
10500b57cec5SDimitry Andric 
10510b57cec5SDimitry Andric   return false;
10520b57cec5SDimitry Andric }
10530b57cec5SDimitry Andric 
addISelPasses()10540b57cec5SDimitry Andric bool TargetPassConfig::addISelPasses() {
10550b57cec5SDimitry Andric   if (TM->useEmulatedTLS())
10560b57cec5SDimitry Andric     addPass(createLowerEmuTLSPass());
10570b57cec5SDimitry Andric 
10580b57cec5SDimitry Andric   addPass(createPreISelIntrinsicLoweringPass());
1059af732203SDimitry Andric   PM->add(createTargetTransformInfoWrapperPass(TM->getTargetIRAnalysis()));
10600b57cec5SDimitry Andric   addIRPasses();
10610b57cec5SDimitry Andric   addCodeGenPrepare();
10620b57cec5SDimitry Andric   addPassesToHandleExceptions();
10630b57cec5SDimitry Andric   addISelPrepare();
10640b57cec5SDimitry Andric 
10650b57cec5SDimitry Andric   return addCoreISelPasses();
10660b57cec5SDimitry Andric }
10670b57cec5SDimitry Andric 
10680b57cec5SDimitry Andric /// -regalloc=... command line option.
useDefaultRegisterAllocator()10690b57cec5SDimitry Andric static FunctionPass *useDefaultRegisterAllocator() { return nullptr; }
10700b57cec5SDimitry Andric static cl::opt<RegisterRegAlloc::FunctionPassCtor, false,
10710b57cec5SDimitry Andric                RegisterPassParser<RegisterRegAlloc>>
10720b57cec5SDimitry Andric     RegAlloc("regalloc", cl::Hidden, cl::init(&useDefaultRegisterAllocator),
10730b57cec5SDimitry Andric              cl::desc("Register allocator to use"));
10740b57cec5SDimitry Andric 
10750b57cec5SDimitry Andric /// Add the complete set of target-independent postISel code generator passes.
10760b57cec5SDimitry Andric ///
10770b57cec5SDimitry Andric /// This can be read as the standard order of major LLVM CodeGen stages. Stages
10780b57cec5SDimitry Andric /// with nontrivial configuration or multiple passes are broken out below in
10790b57cec5SDimitry Andric /// add%Stage routines.
10800b57cec5SDimitry Andric ///
10810b57cec5SDimitry Andric /// Any TargetPassConfig::addXX routine may be overriden by the Target. The
10820b57cec5SDimitry Andric /// addPre/Post methods with empty header implementations allow injecting
10830b57cec5SDimitry Andric /// target-specific fixups just before or after major stages. Additionally,
10840b57cec5SDimitry Andric /// targets have the flexibility to change pass order within a stage by
10850b57cec5SDimitry Andric /// overriding default implementation of add%Stage routines below. Each
10860b57cec5SDimitry Andric /// technique has maintainability tradeoffs because alternate pass orders are
10870b57cec5SDimitry Andric /// not well supported. addPre/Post works better if the target pass is easily
10880b57cec5SDimitry Andric /// tied to a common pass. But if it has subtle dependencies on multiple passes,
10890b57cec5SDimitry Andric /// the target should override the stage instead.
10900b57cec5SDimitry Andric ///
10910b57cec5SDimitry Andric /// TODO: We could use a single addPre/Post(ID) hook to allow pass injection
10920b57cec5SDimitry Andric /// before/after any target-independent pass. But it's currently overkill.
addMachinePasses()10930b57cec5SDimitry Andric void TargetPassConfig::addMachinePasses() {
10940b57cec5SDimitry Andric   AddingMachinePasses = true;
10950b57cec5SDimitry Andric 
10960b57cec5SDimitry Andric   // Add passes that optimize machine instructions in SSA form.
10970b57cec5SDimitry Andric   if (getOptLevel() != CodeGenOpt::None) {
10980b57cec5SDimitry Andric     addMachineSSAOptimization();
10990b57cec5SDimitry Andric   } else {
11000b57cec5SDimitry Andric     // If the target requests it, assign local variables to stack slots relative
11010b57cec5SDimitry Andric     // to one another and simplify frame index references where possible.
11025ffd83dbSDimitry Andric     addPass(&LocalStackSlotAllocationID);
11030b57cec5SDimitry Andric   }
11040b57cec5SDimitry Andric 
11050b57cec5SDimitry Andric   if (TM->Options.EnableIPRA)
11060b57cec5SDimitry Andric     addPass(createRegUsageInfoPropPass());
11070b57cec5SDimitry Andric 
11080b57cec5SDimitry Andric   // Run pre-ra passes.
11090b57cec5SDimitry Andric   addPreRegAlloc();
11100b57cec5SDimitry Andric 
11115ffd83dbSDimitry Andric   // Debugifying the register allocator passes seems to provoke some
11125ffd83dbSDimitry Andric   // non-determinism that affects CodeGen and there doesn't seem to be a point
11135ffd83dbSDimitry Andric   // where it becomes safe again so stop debugifying here.
11145ffd83dbSDimitry Andric   DebugifyIsSafe = false;
11155ffd83dbSDimitry Andric 
11160b57cec5SDimitry Andric   // Run register allocation and passes that are tightly coupled with it,
11170b57cec5SDimitry Andric   // including phi elimination and scheduling.
11180b57cec5SDimitry Andric   if (getOptimizeRegAlloc())
11190b57cec5SDimitry Andric     addOptimizedRegAlloc();
11200b57cec5SDimitry Andric   else
11210b57cec5SDimitry Andric     addFastRegAlloc();
11220b57cec5SDimitry Andric 
11230b57cec5SDimitry Andric   // Run post-ra passes.
11240b57cec5SDimitry Andric   addPostRegAlloc();
11250b57cec5SDimitry Andric 
1126*5f7ddb14SDimitry Andric   addPass(&RemoveRedundantDebugValuesID, false);
1127*5f7ddb14SDimitry Andric 
11285ffd83dbSDimitry Andric   addPass(&FixupStatepointCallerSavedID);
11295ffd83dbSDimitry Andric 
11300b57cec5SDimitry Andric   // Insert prolog/epilog code.  Eliminate abstract frame index references...
11310b57cec5SDimitry Andric   if (getOptLevel() != CodeGenOpt::None) {
11320b57cec5SDimitry Andric     addPass(&PostRAMachineSinkingID);
11330b57cec5SDimitry Andric     addPass(&ShrinkWrapID);
11340b57cec5SDimitry Andric   }
11350b57cec5SDimitry Andric 
11360b57cec5SDimitry Andric   // Prolog/Epilog inserter needs a TargetMachine to instantiate. But only
11370b57cec5SDimitry Andric   // do so if it hasn't been disabled, substituted, or overridden.
11380b57cec5SDimitry Andric   if (!isPassSubstitutedOrOverridden(&PrologEpilogCodeInserterID))
11390b57cec5SDimitry Andric       addPass(createPrologEpilogInserterPass());
11400b57cec5SDimitry Andric 
11410b57cec5SDimitry Andric   /// Add passes that optimize machine instructions after register allocation.
11420b57cec5SDimitry Andric   if (getOptLevel() != CodeGenOpt::None)
11430b57cec5SDimitry Andric     addMachineLateOptimization();
11440b57cec5SDimitry Andric 
11450b57cec5SDimitry Andric   // Expand pseudo instructions before second scheduling pass.
11460b57cec5SDimitry Andric   addPass(&ExpandPostRAPseudosID);
11470b57cec5SDimitry Andric 
11480b57cec5SDimitry Andric   // Run pre-sched2 passes.
11490b57cec5SDimitry Andric   addPreSched2();
11500b57cec5SDimitry Andric 
11510b57cec5SDimitry Andric   if (EnableImplicitNullChecks)
11520b57cec5SDimitry Andric     addPass(&ImplicitNullChecksID);
11530b57cec5SDimitry Andric 
11540b57cec5SDimitry Andric   // Second pass scheduler.
11550b57cec5SDimitry Andric   // Let Target optionally insert this pass by itself at some other
11560b57cec5SDimitry Andric   // point.
11570b57cec5SDimitry Andric   if (getOptLevel() != CodeGenOpt::None &&
11580b57cec5SDimitry Andric       !TM->targetSchedulesPostRAScheduling()) {
11590b57cec5SDimitry Andric     if (MISchedPostRA)
11600b57cec5SDimitry Andric       addPass(&PostMachineSchedulerID);
11610b57cec5SDimitry Andric     else
11620b57cec5SDimitry Andric       addPass(&PostRASchedulerID);
11630b57cec5SDimitry Andric   }
11640b57cec5SDimitry Andric 
11650b57cec5SDimitry Andric   // GC
11660b57cec5SDimitry Andric   if (addGCPasses()) {
11670b57cec5SDimitry Andric     if (PrintGCInfo)
1168af732203SDimitry Andric       addPass(createGCInfoPrinter(dbgs()), false);
11690b57cec5SDimitry Andric   }
11700b57cec5SDimitry Andric 
11710b57cec5SDimitry Andric   // Basic block placement.
11720b57cec5SDimitry Andric   if (getOptLevel() != CodeGenOpt::None)
11730b57cec5SDimitry Andric     addBlockPlacement();
11740b57cec5SDimitry Andric 
117555e4f9d5SDimitry Andric   // Insert before XRay Instrumentation.
11765ffd83dbSDimitry Andric   addPass(&FEntryInserterID);
117755e4f9d5SDimitry Andric 
11785ffd83dbSDimitry Andric   addPass(&XRayInstrumentationID);
11795ffd83dbSDimitry Andric   addPass(&PatchableFunctionID);
118055e4f9d5SDimitry Andric 
1181*5f7ddb14SDimitry Andric   if (EnableFSDiscriminator && !FSNoFinalDiscrim)
1182*5f7ddb14SDimitry Andric     // Add FS discriminators here so that all the instruction duplicates
1183*5f7ddb14SDimitry Andric     // in different BBs get their own discriminators. With this, we can "sum"
1184*5f7ddb14SDimitry Andric     // the SampleFDO counters instead of using MAX. This will improve the
1185*5f7ddb14SDimitry Andric     // SampleFDO profile quality.
1186*5f7ddb14SDimitry Andric     addPass(createMIRAddFSDiscriminatorsPass(
1187*5f7ddb14SDimitry Andric         sampleprof::FSDiscriminatorPass::PassLast));
1188*5f7ddb14SDimitry Andric 
11890b57cec5SDimitry Andric   addPreEmitPass();
11900b57cec5SDimitry Andric 
11910b57cec5SDimitry Andric   if (TM->Options.EnableIPRA)
11920b57cec5SDimitry Andric     // Collect register usage information and produce a register mask of
11930b57cec5SDimitry Andric     // clobbered registers, to be used to optimize call sites.
11940b57cec5SDimitry Andric     addPass(createRegUsageInfoCollector());
11950b57cec5SDimitry Andric 
11965ffd83dbSDimitry Andric   // FIXME: Some backends are incompatible with running the verifier after
11975ffd83dbSDimitry Andric   // addPreEmitPass.  Maybe only pass "false" here for those targets?
11980b57cec5SDimitry Andric   addPass(&FuncletLayoutID, false);
11990b57cec5SDimitry Andric 
12000b57cec5SDimitry Andric   addPass(&StackMapLivenessID, false);
12010b57cec5SDimitry Andric   addPass(&LiveDebugValuesID, false);
12020b57cec5SDimitry Andric 
12030b57cec5SDimitry Andric   if (TM->Options.EnableMachineOutliner && getOptLevel() != CodeGenOpt::None &&
1204af732203SDimitry Andric       EnableMachineOutliner != RunOutliner::NeverOutline) {
1205af732203SDimitry Andric     bool RunOnAllFunctions =
1206af732203SDimitry Andric         (EnableMachineOutliner == RunOutliner::AlwaysOutline);
1207af732203SDimitry Andric     bool AddOutliner =
1208af732203SDimitry Andric         RunOnAllFunctions || TM->Options.SupportsDefaultOutlining;
12090b57cec5SDimitry Andric     if (AddOutliner)
12100b57cec5SDimitry Andric       addPass(createMachineOutlinerPass(RunOnAllFunctions));
12110b57cec5SDimitry Andric   }
12120b57cec5SDimitry Andric 
1213af732203SDimitry Andric   // Machine function splitter uses the basic block sections feature. Both
1214*5f7ddb14SDimitry Andric   // cannot be enabled at the same time. Basic block sections takes precedence.
1215*5f7ddb14SDimitry Andric   // FIXME: In principle, BasicBlockSection::Labels and splitting can used
1216*5f7ddb14SDimitry Andric   // together. Update this check once we have addressed any issues.
1217*5f7ddb14SDimitry Andric   if (TM->getBBSectionsType() != llvm::BasicBlockSection::None) {
1218*5f7ddb14SDimitry Andric     addPass(llvm::createBasicBlockSectionsPass(TM->getBBSectionsFuncListBuf()));
1219*5f7ddb14SDimitry Andric   } else if (TM->Options.EnableMachineFunctionSplitter ||
1220af732203SDimitry Andric              EnableMachineFunctionSplitter) {
1221af732203SDimitry Andric     addPass(createMachineFunctionSplitterPass());
1222af732203SDimitry Andric   }
12235ffd83dbSDimitry Andric 
12240b57cec5SDimitry Andric   // Add passes that directly emit MI after all other MI passes.
12250b57cec5SDimitry Andric   addPreEmitPass2();
12260b57cec5SDimitry Andric 
1227af732203SDimitry Andric   // Insert pseudo probe annotation for callsite profiling
1228af732203SDimitry Andric   if (TM->Options.PseudoProbeForProfiling)
1229af732203SDimitry Andric     addPass(createPseudoProbeInserter());
1230af732203SDimitry Andric 
12310b57cec5SDimitry Andric   AddingMachinePasses = false;
12320b57cec5SDimitry Andric }
12330b57cec5SDimitry Andric 
12340b57cec5SDimitry Andric /// Add passes that optimize machine instructions in SSA form.
addMachineSSAOptimization()12350b57cec5SDimitry Andric void TargetPassConfig::addMachineSSAOptimization() {
12360b57cec5SDimitry Andric   // Pre-ra tail duplication.
12370b57cec5SDimitry Andric   addPass(&EarlyTailDuplicateID);
12380b57cec5SDimitry Andric 
12390b57cec5SDimitry Andric   // Optimize PHIs before DCE: removing dead PHI cycles may make more
12400b57cec5SDimitry Andric   // instructions dead.
12415ffd83dbSDimitry Andric   addPass(&OptimizePHIsID);
12420b57cec5SDimitry Andric 
12430b57cec5SDimitry Andric   // This pass merges large allocas. StackSlotColoring is a different pass
12440b57cec5SDimitry Andric   // which merges spill slots.
12455ffd83dbSDimitry Andric   addPass(&StackColoringID);
12460b57cec5SDimitry Andric 
12470b57cec5SDimitry Andric   // If the target requests it, assign local variables to stack slots relative
12480b57cec5SDimitry Andric   // to one another and simplify frame index references where possible.
12495ffd83dbSDimitry Andric   addPass(&LocalStackSlotAllocationID);
12500b57cec5SDimitry Andric 
12510b57cec5SDimitry Andric   // With optimization, dead code should already be eliminated. However
12520b57cec5SDimitry Andric   // there is one known exception: lowered code for arguments that are only
12530b57cec5SDimitry Andric   // used by tail calls, where the tail calls reuse the incoming stack
12540b57cec5SDimitry Andric   // arguments directly (see t11 in test/CodeGen/X86/sibcall.ll).
12550b57cec5SDimitry Andric   addPass(&DeadMachineInstructionElimID);
12560b57cec5SDimitry Andric 
12570b57cec5SDimitry Andric   // Allow targets to insert passes that improve instruction level parallelism,
12580b57cec5SDimitry Andric   // like if-conversion. Such passes will typically need dominator trees and
12590b57cec5SDimitry Andric   // loop info, just like LICM and CSE below.
12600b57cec5SDimitry Andric   addILPOpts();
12610b57cec5SDimitry Andric 
12625ffd83dbSDimitry Andric   addPass(&EarlyMachineLICMID);
12635ffd83dbSDimitry Andric   addPass(&MachineCSEID);
12640b57cec5SDimitry Andric 
12650b57cec5SDimitry Andric   addPass(&MachineSinkingID);
12660b57cec5SDimitry Andric 
12670b57cec5SDimitry Andric   addPass(&PeepholeOptimizerID);
12680b57cec5SDimitry Andric   // Clean-up the dead code that may have been generated by peephole
12690b57cec5SDimitry Andric   // rewriting.
12700b57cec5SDimitry Andric   addPass(&DeadMachineInstructionElimID);
12710b57cec5SDimitry Andric }
12720b57cec5SDimitry Andric 
12730b57cec5SDimitry Andric //===---------------------------------------------------------------------===//
12740b57cec5SDimitry Andric /// Register Allocation Pass Configuration
12750b57cec5SDimitry Andric //===---------------------------------------------------------------------===//
12760b57cec5SDimitry Andric 
getOptimizeRegAlloc() const12770b57cec5SDimitry Andric bool TargetPassConfig::getOptimizeRegAlloc() const {
12780b57cec5SDimitry Andric   switch (OptimizeRegAlloc) {
12790b57cec5SDimitry Andric   case cl::BOU_UNSET: return getOptLevel() != CodeGenOpt::None;
12800b57cec5SDimitry Andric   case cl::BOU_TRUE:  return true;
12810b57cec5SDimitry Andric   case cl::BOU_FALSE: return false;
12820b57cec5SDimitry Andric   }
12830b57cec5SDimitry Andric   llvm_unreachable("Invalid optimize-regalloc state");
12840b57cec5SDimitry Andric }
12850b57cec5SDimitry Andric 
12860b57cec5SDimitry Andric /// A dummy default pass factory indicates whether the register allocator is
12870b57cec5SDimitry Andric /// overridden on the command line.
12880b57cec5SDimitry Andric static llvm::once_flag InitializeDefaultRegisterAllocatorFlag;
12890b57cec5SDimitry Andric 
12900b57cec5SDimitry Andric static RegisterRegAlloc
12910b57cec5SDimitry Andric defaultRegAlloc("default",
12920b57cec5SDimitry Andric                 "pick register allocator based on -O option",
12930b57cec5SDimitry Andric                 useDefaultRegisterAllocator);
12940b57cec5SDimitry Andric 
initializeDefaultRegisterAllocatorOnce()12950b57cec5SDimitry Andric static void initializeDefaultRegisterAllocatorOnce() {
12960b57cec5SDimitry Andric   if (!RegisterRegAlloc::getDefault())
12970b57cec5SDimitry Andric     RegisterRegAlloc::setDefault(RegAlloc);
12980b57cec5SDimitry Andric }
12990b57cec5SDimitry Andric 
13000b57cec5SDimitry Andric /// Instantiate the default register allocator pass for this target for either
13010b57cec5SDimitry Andric /// the optimized or unoptimized allocation path. This will be added to the pass
13020b57cec5SDimitry Andric /// manager by addFastRegAlloc in the unoptimized case or addOptimizedRegAlloc
13030b57cec5SDimitry Andric /// in the optimized case.
13040b57cec5SDimitry Andric ///
13050b57cec5SDimitry Andric /// A target that uses the standard regalloc pass order for fast or optimized
13060b57cec5SDimitry Andric /// allocation may still override this for per-target regalloc
13070b57cec5SDimitry Andric /// selection. But -regalloc=... always takes precedence.
createTargetRegisterAllocator(bool Optimized)13080b57cec5SDimitry Andric FunctionPass *TargetPassConfig::createTargetRegisterAllocator(bool Optimized) {
13090b57cec5SDimitry Andric   if (Optimized)
13100b57cec5SDimitry Andric     return createGreedyRegisterAllocator();
13110b57cec5SDimitry Andric   else
13120b57cec5SDimitry Andric     return createFastRegisterAllocator();
13130b57cec5SDimitry Andric }
13140b57cec5SDimitry Andric 
13150b57cec5SDimitry Andric /// Find and instantiate the register allocation pass requested by this target
13160b57cec5SDimitry Andric /// at the current optimization level.  Different register allocators are
13170b57cec5SDimitry Andric /// defined as separate passes because they may require different analysis.
13180b57cec5SDimitry Andric ///
13190b57cec5SDimitry Andric /// This helper ensures that the regalloc= option is always available,
13200b57cec5SDimitry Andric /// even for targets that override the default allocator.
13210b57cec5SDimitry Andric ///
13220b57cec5SDimitry Andric /// FIXME: When MachinePassRegistry register pass IDs instead of function ptrs,
13230b57cec5SDimitry Andric /// this can be folded into addPass.
createRegAllocPass(bool Optimized)13240b57cec5SDimitry Andric FunctionPass *TargetPassConfig::createRegAllocPass(bool Optimized) {
13250b57cec5SDimitry Andric   // Initialize the global default.
13260b57cec5SDimitry Andric   llvm::call_once(InitializeDefaultRegisterAllocatorFlag,
13270b57cec5SDimitry Andric                   initializeDefaultRegisterAllocatorOnce);
13280b57cec5SDimitry Andric 
13290b57cec5SDimitry Andric   RegisterRegAlloc::FunctionPassCtor Ctor = RegisterRegAlloc::getDefault();
13300b57cec5SDimitry Andric   if (Ctor != useDefaultRegisterAllocator)
13310b57cec5SDimitry Andric     return Ctor();
13320b57cec5SDimitry Andric 
13330b57cec5SDimitry Andric   // With no -regalloc= override, ask the target for a regalloc pass.
13340b57cec5SDimitry Andric   return createTargetRegisterAllocator(Optimized);
13350b57cec5SDimitry Andric }
13360b57cec5SDimitry Andric 
addRegAssignAndRewriteFast()1337af732203SDimitry Andric bool TargetPassConfig::addRegAssignAndRewriteFast() {
1338*5f7ddb14SDimitry Andric   if (RegAlloc != (RegisterRegAlloc::FunctionPassCtor)&useDefaultRegisterAllocator &&
1339*5f7ddb14SDimitry Andric       RegAlloc != (RegisterRegAlloc::FunctionPassCtor)&createFastRegisterAllocator)
13400b57cec5SDimitry Andric     report_fatal_error("Must use fast (default) register allocator for unoptimized regalloc.");
13410b57cec5SDimitry Andric 
13420b57cec5SDimitry Andric   addPass(createRegAllocPass(false));
1343*5f7ddb14SDimitry Andric 
1344*5f7ddb14SDimitry Andric   // Allow targets to change the register assignments after
1345*5f7ddb14SDimitry Andric   // fast register allocation.
1346*5f7ddb14SDimitry Andric   addPostFastRegAllocRewrite();
13470b57cec5SDimitry Andric   return true;
13480b57cec5SDimitry Andric }
13490b57cec5SDimitry Andric 
addRegAssignAndRewriteOptimized()1350af732203SDimitry Andric bool TargetPassConfig::addRegAssignAndRewriteOptimized() {
13510b57cec5SDimitry Andric   // Add the selected register allocation pass.
13520b57cec5SDimitry Andric   addPass(createRegAllocPass(true));
13530b57cec5SDimitry Andric 
13540b57cec5SDimitry Andric   // Allow targets to change the register assignments before rewriting.
13550b57cec5SDimitry Andric   addPreRewrite();
13560b57cec5SDimitry Andric 
13570b57cec5SDimitry Andric   // Finally rewrite virtual registers.
13580b57cec5SDimitry Andric   addPass(&VirtRegRewriterID);
13595ffd83dbSDimitry Andric 
13600b57cec5SDimitry Andric   return true;
13610b57cec5SDimitry Andric }
13620b57cec5SDimitry Andric 
13630b57cec5SDimitry Andric /// Return true if the default global register allocator is in use and
13640b57cec5SDimitry Andric /// has not be overriden on the command line with '-regalloc=...'
usingDefaultRegAlloc() const13650b57cec5SDimitry Andric bool TargetPassConfig::usingDefaultRegAlloc() const {
13660b57cec5SDimitry Andric   return RegAlloc.getNumOccurrences() == 0;
13670b57cec5SDimitry Andric }
13680b57cec5SDimitry Andric 
13690b57cec5SDimitry Andric /// Add the minimum set of target-independent passes that are required for
13700b57cec5SDimitry Andric /// register allocation. No coalescing or scheduling.
addFastRegAlloc()13710b57cec5SDimitry Andric void TargetPassConfig::addFastRegAlloc() {
13720b57cec5SDimitry Andric   addPass(&PHIEliminationID, false);
13730b57cec5SDimitry Andric   addPass(&TwoAddressInstructionPassID, false);
13740b57cec5SDimitry Andric 
1375af732203SDimitry Andric   addRegAssignAndRewriteFast();
13760b57cec5SDimitry Andric }
13770b57cec5SDimitry Andric 
13780b57cec5SDimitry Andric /// Add standard target-independent passes that are tightly coupled with
13790b57cec5SDimitry Andric /// optimized register allocation, including coalescing, machine instruction
13800b57cec5SDimitry Andric /// scheduling, and register allocation itself.
addOptimizedRegAlloc()13810b57cec5SDimitry Andric void TargetPassConfig::addOptimizedRegAlloc() {
13820b57cec5SDimitry Andric   addPass(&DetectDeadLanesID, false);
13830b57cec5SDimitry Andric 
13840b57cec5SDimitry Andric   addPass(&ProcessImplicitDefsID, false);
13850b57cec5SDimitry Andric 
13860b57cec5SDimitry Andric   // LiveVariables currently requires pure SSA form.
13870b57cec5SDimitry Andric   //
13880b57cec5SDimitry Andric   // FIXME: Once TwoAddressInstruction pass no longer uses kill flags,
13890b57cec5SDimitry Andric   // LiveVariables can be removed completely, and LiveIntervals can be directly
13900b57cec5SDimitry Andric   // computed. (We still either need to regenerate kill flags after regalloc, or
13910b57cec5SDimitry Andric   // preferably fix the scavenger to not depend on them).
1392af732203SDimitry Andric   // FIXME: UnreachableMachineBlockElim is a dependant pass of LiveVariables.
1393af732203SDimitry Andric   // When LiveVariables is removed this has to be removed/moved either.
1394af732203SDimitry Andric   // Explicit addition of UnreachableMachineBlockElim allows stopping before or
1395af732203SDimitry Andric   // after it with -stop-before/-stop-after.
1396af732203SDimitry Andric   addPass(&UnreachableMachineBlockElimID, false);
13970b57cec5SDimitry Andric   addPass(&LiveVariablesID, false);
13980b57cec5SDimitry Andric 
13990b57cec5SDimitry Andric   // Edge splitting is smarter with machine loop info.
14000b57cec5SDimitry Andric   addPass(&MachineLoopInfoID, false);
14010b57cec5SDimitry Andric   addPass(&PHIEliminationID, false);
14020b57cec5SDimitry Andric 
14030b57cec5SDimitry Andric   // Eventually, we want to run LiveIntervals before PHI elimination.
14040b57cec5SDimitry Andric   if (EarlyLiveIntervals)
14050b57cec5SDimitry Andric     addPass(&LiveIntervalsID, false);
14060b57cec5SDimitry Andric 
14070b57cec5SDimitry Andric   addPass(&TwoAddressInstructionPassID, false);
14080b57cec5SDimitry Andric   addPass(&RegisterCoalescerID);
14090b57cec5SDimitry Andric 
14100b57cec5SDimitry Andric   // The machine scheduler may accidentally create disconnected components
14110b57cec5SDimitry Andric   // when moving subregister definitions around, avoid this by splitting them to
14120b57cec5SDimitry Andric   // separate vregs before. Splitting can also improve reg. allocation quality.
14130b57cec5SDimitry Andric   addPass(&RenameIndependentSubregsID);
14140b57cec5SDimitry Andric 
14150b57cec5SDimitry Andric   // PreRA instruction scheduling.
14160b57cec5SDimitry Andric   addPass(&MachineSchedulerID);
14170b57cec5SDimitry Andric 
1418af732203SDimitry Andric   if (addRegAssignAndRewriteOptimized()) {
1419af732203SDimitry Andric     // Perform stack slot coloring and post-ra machine LICM.
1420af732203SDimitry Andric     //
1421af732203SDimitry Andric     // FIXME: Re-enable coloring with register when it's capable of adding
1422af732203SDimitry Andric     // kill markers.
1423af732203SDimitry Andric     addPass(&StackSlotColoringID);
1424af732203SDimitry Andric 
14250b57cec5SDimitry Andric     // Allow targets to expand pseudo instructions depending on the choice of
14260b57cec5SDimitry Andric     // registers before MachineCopyPropagation.
14270b57cec5SDimitry Andric     addPostRewrite();
14280b57cec5SDimitry Andric 
14290b57cec5SDimitry Andric     // Copy propagate to forward register uses and try to eliminate COPYs that
14300b57cec5SDimitry Andric     // were not coalesced.
14310b57cec5SDimitry Andric     addPass(&MachineCopyPropagationID);
14320b57cec5SDimitry Andric 
14330b57cec5SDimitry Andric     // Run post-ra machine LICM to hoist reloads / remats.
14340b57cec5SDimitry Andric     //
14350b57cec5SDimitry Andric     // FIXME: can this move into MachineLateOptimization?
14360b57cec5SDimitry Andric     addPass(&MachineLICMID);
14370b57cec5SDimitry Andric   }
14380b57cec5SDimitry Andric }
14390b57cec5SDimitry Andric 
14400b57cec5SDimitry Andric //===---------------------------------------------------------------------===//
14410b57cec5SDimitry Andric /// Post RegAlloc Pass Configuration
14420b57cec5SDimitry Andric //===---------------------------------------------------------------------===//
14430b57cec5SDimitry Andric 
14440b57cec5SDimitry Andric /// Add passes that optimize machine instructions after register allocation.
addMachineLateOptimization()14450b57cec5SDimitry Andric void TargetPassConfig::addMachineLateOptimization() {
14460b57cec5SDimitry Andric   // Branch folding must be run after regalloc and prolog/epilog insertion.
14470b57cec5SDimitry Andric   addPass(&BranchFolderPassID);
14480b57cec5SDimitry Andric 
14490b57cec5SDimitry Andric   // Tail duplication.
14500b57cec5SDimitry Andric   // Note that duplicating tail just increases code size and degrades
14510b57cec5SDimitry Andric   // performance for targets that require Structured Control Flow.
14520b57cec5SDimitry Andric   // In addition it can also make CFG irreducible. Thus we disable it.
14530b57cec5SDimitry Andric   if (!TM->requiresStructuredCFG())
14540b57cec5SDimitry Andric     addPass(&TailDuplicateID);
14550b57cec5SDimitry Andric 
14560b57cec5SDimitry Andric   // Copy propagation.
14570b57cec5SDimitry Andric   addPass(&MachineCopyPropagationID);
14580b57cec5SDimitry Andric }
14590b57cec5SDimitry Andric 
14600b57cec5SDimitry Andric /// Add standard GC passes.
addGCPasses()14610b57cec5SDimitry Andric bool TargetPassConfig::addGCPasses() {
14620b57cec5SDimitry Andric   addPass(&GCMachineCodeAnalysisID, false);
14630b57cec5SDimitry Andric   return true;
14640b57cec5SDimitry Andric }
14650b57cec5SDimitry Andric 
14660b57cec5SDimitry Andric /// Add standard basic block placement passes.
addBlockPlacement()14670b57cec5SDimitry Andric void TargetPassConfig::addBlockPlacement() {
14680b57cec5SDimitry Andric   if (addPass(&MachineBlockPlacementID)) {
14690b57cec5SDimitry Andric     // Run a separate pass to collect block placement statistics.
14700b57cec5SDimitry Andric     if (EnableBlockPlacementStats)
14710b57cec5SDimitry Andric       addPass(&MachineBlockPlacementStatsID);
14720b57cec5SDimitry Andric   }
14730b57cec5SDimitry Andric }
14740b57cec5SDimitry Andric 
14750b57cec5SDimitry Andric //===---------------------------------------------------------------------===//
14760b57cec5SDimitry Andric /// GlobalISel Configuration
14770b57cec5SDimitry Andric //===---------------------------------------------------------------------===//
isGlobalISelAbortEnabled() const14780b57cec5SDimitry Andric bool TargetPassConfig::isGlobalISelAbortEnabled() const {
14790b57cec5SDimitry Andric   return TM->Options.GlobalISelAbort == GlobalISelAbortMode::Enable;
14800b57cec5SDimitry Andric }
14810b57cec5SDimitry Andric 
reportDiagnosticWhenGlobalISelFallback() const14820b57cec5SDimitry Andric bool TargetPassConfig::reportDiagnosticWhenGlobalISelFallback() const {
14830b57cec5SDimitry Andric   return TM->Options.GlobalISelAbort == GlobalISelAbortMode::DisableWithDiag;
14840b57cec5SDimitry Andric }
14850b57cec5SDimitry Andric 
isGISelCSEEnabled() const14860b57cec5SDimitry Andric bool TargetPassConfig::isGISelCSEEnabled() const {
14870b57cec5SDimitry Andric   return true;
14880b57cec5SDimitry Andric }
14890b57cec5SDimitry Andric 
getCSEConfig() const14900b57cec5SDimitry Andric std::unique_ptr<CSEConfigBase> TargetPassConfig::getCSEConfig() const {
14918bcb0991SDimitry Andric   return std::make_unique<CSEConfigBase>();
14920b57cec5SDimitry Andric }
1493