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