1a580b014SDimitry Andric //===- TargetPassConfig.cpp - Target independent code generation passes ---===//
23ca95b02SDimitry Andric //
33ca95b02SDimitry Andric //                     The LLVM Compiler Infrastructure
43ca95b02SDimitry Andric //
53ca95b02SDimitry Andric // This file is distributed under the University of Illinois Open Source
63ca95b02SDimitry Andric // License. See LICENSE.TXT for details.
73ca95b02SDimitry Andric //
83ca95b02SDimitry Andric //===----------------------------------------------------------------------===//
93ca95b02SDimitry Andric //
103ca95b02SDimitry Andric // This file defines interfaces to access the target independent code
113ca95b02SDimitry Andric // generation passes provided by the LLVM backend.
123ca95b02SDimitry Andric //
133ca95b02SDimitry Andric //===---------------------------------------------------------------------===//
143ca95b02SDimitry Andric 
153ca95b02SDimitry Andric #include "llvm/CodeGen/TargetPassConfig.h"
16a580b014SDimitry Andric #include "llvm/ADT/DenseMap.h"
17a580b014SDimitry Andric #include "llvm/ADT/SmallVector.h"
18a580b014SDimitry Andric #include "llvm/ADT/StringRef.h"
193ca95b02SDimitry Andric #include "llvm/Analysis/BasicAliasAnalysis.h"
203ca95b02SDimitry Andric #include "llvm/Analysis/CFLAndersAliasAnalysis.h"
213ca95b02SDimitry Andric #include "llvm/Analysis/CFLSteensAliasAnalysis.h"
223ca95b02SDimitry Andric #include "llvm/Analysis/CallGraphSCCPass.h"
233ca95b02SDimitry Andric #include "llvm/Analysis/ScopedNoAliasAA.h"
24db17bf38SDimitry Andric #include "llvm/Analysis/TargetTransformInfo.h"
253ca95b02SDimitry Andric #include "llvm/Analysis/TypeBasedAliasAnalysis.h"
263ca95b02SDimitry Andric #include "llvm/CodeGen/MachineFunctionPass.h"
27a580b014SDimitry Andric #include "llvm/CodeGen/MachinePassRegistry.h"
28a580b014SDimitry Andric #include "llvm/CodeGen/Passes.h"
293ca95b02SDimitry Andric #include "llvm/CodeGen/RegAllocRegistry.h"
303ca95b02SDimitry Andric #include "llvm/IR/IRPrintingPasses.h"
313ca95b02SDimitry Andric #include "llvm/IR/LegacyPassManager.h"
323ca95b02SDimitry Andric #include "llvm/IR/Verifier.h"
333ca95b02SDimitry Andric #include "llvm/MC/MCAsmInfo.h"
34a580b014SDimitry Andric #include "llvm/MC/MCTargetOptions.h"
35a580b014SDimitry Andric #include "llvm/Pass.h"
36a580b014SDimitry Andric #include "llvm/Support/CodeGen.h"
37a580b014SDimitry Andric #include "llvm/Support/CommandLine.h"
38a580b014SDimitry Andric #include "llvm/Support/Compiler.h"
393ca95b02SDimitry Andric #include "llvm/Support/Debug.h"
403ca95b02SDimitry Andric #include "llvm/Support/ErrorHandling.h"
41a580b014SDimitry Andric #include "llvm/Support/Threading.h"
42*b5893f02SDimitry Andric #include "llvm/Support/SaveAndRestore.h"
433ca95b02SDimitry Andric #include "llvm/Target/TargetMachine.h"
443ca95b02SDimitry Andric #include "llvm/Transforms/Scalar.h"
454ba319b5SDimitry Andric #include "llvm/Transforms/Utils.h"
463ca95b02SDimitry Andric #include "llvm/Transforms/Utils/SymbolRewriter.h"
47a580b014SDimitry Andric #include <cassert>
48a580b014SDimitry Andric #include <string>
493ca95b02SDimitry Andric 
503ca95b02SDimitry Andric using namespace llvm;
513ca95b02SDimitry Andric 
522cab237bSDimitry Andric cl::opt<bool> EnableIPRA("enable-ipra", cl::init(false), cl::Hidden,
532cab237bSDimitry Andric                          cl::desc("Enable interprocedural register allocation "
542cab237bSDimitry Andric                                   "to reduce load/store at procedure calls."));
55d88c1a5aSDimitry Andric static cl::opt<bool> DisablePostRASched("disable-post-ra", cl::Hidden,
56d88c1a5aSDimitry Andric     cl::desc("Disable Post Regalloc Scheduler"));
573ca95b02SDimitry Andric static cl::opt<bool> DisableBranchFold("disable-branch-fold", cl::Hidden,
583ca95b02SDimitry Andric     cl::desc("Disable branch folding"));
593ca95b02SDimitry Andric static cl::opt<bool> DisableTailDuplicate("disable-tail-duplicate", cl::Hidden,
603ca95b02SDimitry Andric     cl::desc("Disable tail duplication"));
613ca95b02SDimitry Andric static cl::opt<bool> DisableEarlyTailDup("disable-early-taildup", cl::Hidden,
623ca95b02SDimitry Andric     cl::desc("Disable pre-register allocation tail duplication"));
633ca95b02SDimitry Andric static cl::opt<bool> DisableBlockPlacement("disable-block-placement",
643ca95b02SDimitry Andric     cl::Hidden, cl::desc("Disable probability-driven block placement"));
653ca95b02SDimitry Andric static cl::opt<bool> EnableBlockPlacementStats("enable-block-placement-stats",
663ca95b02SDimitry Andric     cl::Hidden, cl::desc("Collect probability-driven block placement stats"));
673ca95b02SDimitry Andric static cl::opt<bool> DisableSSC("disable-ssc", cl::Hidden,
683ca95b02SDimitry Andric     cl::desc("Disable Stack Slot Coloring"));
693ca95b02SDimitry Andric static cl::opt<bool> DisableMachineDCE("disable-machine-dce", cl::Hidden,
703ca95b02SDimitry Andric     cl::desc("Disable Machine Dead Code Elimination"));
713ca95b02SDimitry Andric static cl::opt<bool> DisableEarlyIfConversion("disable-early-ifcvt", cl::Hidden,
723ca95b02SDimitry Andric     cl::desc("Disable Early If-conversion"));
733ca95b02SDimitry Andric static cl::opt<bool> DisableMachineLICM("disable-machine-licm", cl::Hidden,
743ca95b02SDimitry Andric     cl::desc("Disable Machine LICM"));
753ca95b02SDimitry Andric static cl::opt<bool> DisableMachineCSE("disable-machine-cse", cl::Hidden,
763ca95b02SDimitry Andric     cl::desc("Disable Machine Common Subexpression Elimination"));
773ca95b02SDimitry Andric static cl::opt<cl::boolOrDefault> OptimizeRegAlloc(
783ca95b02SDimitry Andric     "optimize-regalloc", cl::Hidden,
793ca95b02SDimitry Andric     cl::desc("Enable optimized register allocation compilation path."));
803ca95b02SDimitry Andric static cl::opt<bool> DisablePostRAMachineLICM("disable-postra-machine-licm",
813ca95b02SDimitry Andric     cl::Hidden,
823ca95b02SDimitry Andric     cl::desc("Disable Machine LICM"));
833ca95b02SDimitry Andric static cl::opt<bool> DisableMachineSink("disable-machine-sink", cl::Hidden,
843ca95b02SDimitry Andric     cl::desc("Disable Machine Sinking"));
854ba319b5SDimitry Andric static cl::opt<bool> DisablePostRAMachineSink("disable-postra-machine-sink",
864ba319b5SDimitry Andric     cl::Hidden,
874ba319b5SDimitry Andric     cl::desc("Disable PostRA Machine Sinking"));
883ca95b02SDimitry Andric static cl::opt<bool> DisableLSR("disable-lsr", cl::Hidden,
893ca95b02SDimitry Andric     cl::desc("Disable Loop Strength Reduction Pass"));
903ca95b02SDimitry Andric static cl::opt<bool> DisableConstantHoisting("disable-constant-hoisting",
913ca95b02SDimitry Andric     cl::Hidden, cl::desc("Disable ConstantHoisting"));
923ca95b02SDimitry Andric static cl::opt<bool> DisableCGP("disable-cgp", cl::Hidden,
933ca95b02SDimitry Andric     cl::desc("Disable Codegen Prepare"));
943ca95b02SDimitry Andric static cl::opt<bool> DisableCopyProp("disable-copyprop", cl::Hidden,
953ca95b02SDimitry Andric     cl::desc("Disable Copy Propagation pass"));
963ca95b02SDimitry Andric static cl::opt<bool> DisablePartialLibcallInlining("disable-partial-libcall-inlining",
973ca95b02SDimitry Andric     cl::Hidden, cl::desc("Disable Partial Libcall Inlining"));
983ca95b02SDimitry Andric static cl::opt<bool> EnableImplicitNullChecks(
993ca95b02SDimitry Andric     "enable-implicit-null-checks",
1003ca95b02SDimitry Andric     cl::desc("Fold null checks into faulting memory operations"),
1012cab237bSDimitry Andric     cl::init(false), cl::Hidden);
1024ba319b5SDimitry Andric static cl::opt<bool> DisableMergeICmps("disable-mergeicmps",
1034ba319b5SDimitry Andric     cl::desc("Disable MergeICmps Pass"),
1042cab237bSDimitry Andric     cl::init(false), cl::Hidden);
1053ca95b02SDimitry Andric static cl::opt<bool> PrintLSR("print-lsr-output", cl::Hidden,
1063ca95b02SDimitry Andric     cl::desc("Print LLVM IR produced by the loop-reduce pass"));
1073ca95b02SDimitry Andric static cl::opt<bool> PrintISelInput("print-isel-input", cl::Hidden,
1083ca95b02SDimitry Andric     cl::desc("Print LLVM IR input to isel pass"));
1093ca95b02SDimitry Andric static cl::opt<bool> PrintGCInfo("print-gc", cl::Hidden,
1103ca95b02SDimitry Andric     cl::desc("Dump garbage collector data"));
111*b5893f02SDimitry Andric static cl::opt<cl::boolOrDefault>
112*b5893f02SDimitry Andric     VerifyMachineCode("verify-machineinstrs", cl::Hidden,
1133ca95b02SDimitry Andric                       cl::desc("Verify generated machine code"),
1143ca95b02SDimitry Andric                       cl::ZeroOrMore);
1154ba319b5SDimitry Andric enum RunOutliner { AlwaysOutline, NeverOutline, TargetDefault };
1164ba319b5SDimitry Andric // Enable or disable the MachineOutliner.
1174ba319b5SDimitry Andric static cl::opt<RunOutliner> EnableMachineOutliner(
1184ba319b5SDimitry Andric     "enable-machine-outliner", cl::desc("Enable the machine outliner"),
1194ba319b5SDimitry Andric     cl::Hidden, cl::ValueOptional, cl::init(TargetDefault),
1204ba319b5SDimitry Andric     cl::values(clEnumValN(AlwaysOutline, "always",
1214ba319b5SDimitry Andric                           "Run on all functions guaranteed to be beneficial"),
1224ba319b5SDimitry Andric                clEnumValN(NeverOutline, "never", "Disable all outlining"),
1234ba319b5SDimitry Andric                // Sentinel value for unspecified option.
1244ba319b5SDimitry Andric                clEnumValN(AlwaysOutline, "", "")));
125db17bf38SDimitry Andric // Enable or disable FastISel. Both options are needed, because
126db17bf38SDimitry Andric // FastISel is enabled by default with -fast, and we wish to be
127db17bf38SDimitry Andric // able to enable or disable fast-isel independently from -O0.
128db17bf38SDimitry Andric static cl::opt<cl::boolOrDefault>
129db17bf38SDimitry Andric EnableFastISelOption("fast-isel", cl::Hidden,
130db17bf38SDimitry Andric   cl::desc("Enable the \"fast\" instruction selector"));
131db17bf38SDimitry Andric 
1324ba319b5SDimitry Andric static cl::opt<cl::boolOrDefault> EnableGlobalISelOption(
1334ba319b5SDimitry Andric     "global-isel", cl::Hidden,
134db17bf38SDimitry Andric     cl::desc("Enable the \"global\" instruction selector"));
1353ca95b02SDimitry Andric 
1362cab237bSDimitry Andric static cl::opt<std::string> PrintMachineInstrs(
1372cab237bSDimitry Andric     "print-machineinstrs", cl::ValueOptional, cl::desc("Print machine instrs"),
1382cab237bSDimitry Andric     cl::value_desc("pass-name"), cl::init("option-unspecified"), cl::Hidden);
1393ca95b02SDimitry Andric 
140*b5893f02SDimitry Andric static cl::opt<GlobalISelAbortMode> EnableGlobalISelAbort(
141d88c1a5aSDimitry Andric     "global-isel-abort", cl::Hidden,
142d88c1a5aSDimitry Andric     cl::desc("Enable abort calls when \"global\" instruction selection "
143*b5893f02SDimitry Andric              "fails to lower/select an instruction"),
144*b5893f02SDimitry Andric     cl::values(
145*b5893f02SDimitry Andric         clEnumValN(GlobalISelAbortMode::Disable, "0", "Disable the abort"),
146*b5893f02SDimitry Andric         clEnumValN(GlobalISelAbortMode::Enable, "1", "Enable the abort"),
147*b5893f02SDimitry Andric         clEnumValN(GlobalISelAbortMode::DisableWithDiag, "2",
148*b5893f02SDimitry Andric                    "Disable the abort but emit a diagnostic on failure")));
149d88c1a5aSDimitry Andric 
1503ca95b02SDimitry Andric // Temporary option to allow experimenting with MachineScheduler as a post-RA
1513ca95b02SDimitry Andric // scheduler. Targets can "properly" enable this with
1523ca95b02SDimitry Andric // substitutePass(&PostRASchedulerID, &PostMachineSchedulerID).
1533ca95b02SDimitry Andric // Targets can return true in targetSchedulesPostRAScheduling() and
1543ca95b02SDimitry Andric // insert a PostRA scheduling pass wherever it wants.
1553ca95b02SDimitry Andric cl::opt<bool> MISchedPostRA("misched-postra", cl::Hidden,
1563ca95b02SDimitry Andric   cl::desc("Run MachineScheduler post regalloc (independent of preRA sched)"));
1573ca95b02SDimitry Andric 
1583ca95b02SDimitry Andric // Experimental option to run live interval analysis early.
1593ca95b02SDimitry Andric static cl::opt<bool> EarlyLiveIntervals("early-live-intervals", cl::Hidden,
1603ca95b02SDimitry Andric     cl::desc("Run live interval analysis earlier in the pipeline"));
1613ca95b02SDimitry Andric 
1623ca95b02SDimitry Andric // Experimental option to use CFL-AA in codegen
1633ca95b02SDimitry Andric enum class CFLAAType { None, Steensgaard, Andersen, Both };
1643ca95b02SDimitry Andric static cl::opt<CFLAAType> UseCFLAA(
1653ca95b02SDimitry Andric     "use-cfl-aa-in-codegen", cl::init(CFLAAType::None), cl::Hidden,
1663ca95b02SDimitry Andric     cl::desc("Enable the new, experimental CFL alias analysis in CodeGen"),
1673ca95b02SDimitry Andric     cl::values(clEnumValN(CFLAAType::None, "none", "Disable CFL-AA"),
1683ca95b02SDimitry Andric                clEnumValN(CFLAAType::Steensgaard, "steens",
1693ca95b02SDimitry Andric                           "Enable unification-based CFL-AA"),
1703ca95b02SDimitry Andric                clEnumValN(CFLAAType::Andersen, "anders",
1713ca95b02SDimitry Andric                           "Enable inclusion-based CFL-AA"),
1723ca95b02SDimitry Andric                clEnumValN(CFLAAType::Both, "both",
173d88c1a5aSDimitry Andric                           "Enable both variants of CFL-AA")));
1743ca95b02SDimitry Andric 
1752cab237bSDimitry Andric /// Option names for limiting the codegen pipeline.
1762cab237bSDimitry Andric /// Those are used in error reporting and we didn't want
1772cab237bSDimitry Andric /// to duplicate their names all over the place.
1782cab237bSDimitry Andric const char *StartAfterOptName = "start-after";
1792cab237bSDimitry Andric const char *StartBeforeOptName = "start-before";
1802cab237bSDimitry Andric const char *StopAfterOptName = "stop-after";
1812cab237bSDimitry Andric const char *StopBeforeOptName = "stop-before";
1822cab237bSDimitry Andric 
1832cab237bSDimitry Andric static cl::opt<std::string>
1842cab237bSDimitry Andric     StartAfterOpt(StringRef(StartAfterOptName),
1852cab237bSDimitry Andric                   cl::desc("Resume compilation after a specific pass"),
1862cab237bSDimitry Andric                   cl::value_desc("pass-name"), cl::init(""), cl::Hidden);
1872cab237bSDimitry Andric 
1882cab237bSDimitry Andric static cl::opt<std::string>
1892cab237bSDimitry Andric     StartBeforeOpt(StringRef(StartBeforeOptName),
1902cab237bSDimitry Andric                    cl::desc("Resume compilation before a specific pass"),
1912cab237bSDimitry Andric                    cl::value_desc("pass-name"), cl::init(""), cl::Hidden);
1922cab237bSDimitry Andric 
1932cab237bSDimitry Andric static cl::opt<std::string>
1942cab237bSDimitry Andric     StopAfterOpt(StringRef(StopAfterOptName),
1952cab237bSDimitry Andric                  cl::desc("Stop compilation after a specific pass"),
1962cab237bSDimitry Andric                  cl::value_desc("pass-name"), cl::init(""), cl::Hidden);
1972cab237bSDimitry Andric 
1982cab237bSDimitry Andric static cl::opt<std::string>
1992cab237bSDimitry Andric     StopBeforeOpt(StringRef(StopBeforeOptName),
2002cab237bSDimitry Andric                   cl::desc("Stop compilation before a specific pass"),
2012cab237bSDimitry Andric                   cl::value_desc("pass-name"), cl::init(""), cl::Hidden);
2022cab237bSDimitry Andric 
2033ca95b02SDimitry Andric /// Allow standard passes to be disabled by command line options. This supports
2043ca95b02SDimitry Andric /// simple binary flags that either suppress the pass or do nothing.
2053ca95b02SDimitry Andric /// i.e. -disable-mypass=false has no effect.
2063ca95b02SDimitry Andric /// These should be converted to boolOrDefault in order to use applyOverride.
applyDisable(IdentifyingPassPtr PassID,bool Override)2073ca95b02SDimitry Andric static IdentifyingPassPtr applyDisable(IdentifyingPassPtr PassID,
2083ca95b02SDimitry Andric                                        bool Override) {
2093ca95b02SDimitry Andric   if (Override)
2103ca95b02SDimitry Andric     return IdentifyingPassPtr();
2113ca95b02SDimitry Andric   return PassID;
2123ca95b02SDimitry Andric }
2133ca95b02SDimitry Andric 
2143ca95b02SDimitry Andric /// Allow standard passes to be disabled by the command line, regardless of who
2153ca95b02SDimitry Andric /// is adding the pass.
2163ca95b02SDimitry Andric ///
2173ca95b02SDimitry Andric /// StandardID is the pass identified in the standard pass pipeline and provided
2183ca95b02SDimitry Andric /// to addPass(). It may be a target-specific ID in the case that the target
2193ca95b02SDimitry Andric /// directly adds its own pass, but in that case we harmlessly fall through.
2203ca95b02SDimitry Andric ///
2213ca95b02SDimitry Andric /// TargetID is the pass that the target has configured to override StandardID.
2223ca95b02SDimitry Andric ///
2233ca95b02SDimitry Andric /// StandardID may be a pseudo ID. In that case TargetID is the name of the real
2243ca95b02SDimitry Andric /// pass to run. This allows multiple options to control a single pass depending
2253ca95b02SDimitry Andric /// on where in the pipeline that pass is added.
overridePass(AnalysisID StandardID,IdentifyingPassPtr TargetID)2263ca95b02SDimitry Andric static IdentifyingPassPtr overridePass(AnalysisID StandardID,
2273ca95b02SDimitry Andric                                        IdentifyingPassPtr TargetID) {
2283ca95b02SDimitry Andric   if (StandardID == &PostRASchedulerID)
229d88c1a5aSDimitry Andric     return applyDisable(TargetID, DisablePostRASched);
2303ca95b02SDimitry Andric 
2313ca95b02SDimitry Andric   if (StandardID == &BranchFolderPassID)
2323ca95b02SDimitry Andric     return applyDisable(TargetID, DisableBranchFold);
2333ca95b02SDimitry Andric 
2343ca95b02SDimitry Andric   if (StandardID == &TailDuplicateID)
2353ca95b02SDimitry Andric     return applyDisable(TargetID, DisableTailDuplicate);
2363ca95b02SDimitry Andric 
2374ba319b5SDimitry Andric   if (StandardID == &EarlyTailDuplicateID)
2383ca95b02SDimitry Andric     return applyDisable(TargetID, DisableEarlyTailDup);
2393ca95b02SDimitry Andric 
2403ca95b02SDimitry Andric   if (StandardID == &MachineBlockPlacementID)
2413ca95b02SDimitry Andric     return applyDisable(TargetID, DisableBlockPlacement);
2423ca95b02SDimitry Andric 
2433ca95b02SDimitry Andric   if (StandardID == &StackSlotColoringID)
2443ca95b02SDimitry Andric     return applyDisable(TargetID, DisableSSC);
2453ca95b02SDimitry Andric 
2463ca95b02SDimitry Andric   if (StandardID == &DeadMachineInstructionElimID)
2473ca95b02SDimitry Andric     return applyDisable(TargetID, DisableMachineDCE);
2483ca95b02SDimitry Andric 
2493ca95b02SDimitry Andric   if (StandardID == &EarlyIfConverterID)
2503ca95b02SDimitry Andric     return applyDisable(TargetID, DisableEarlyIfConversion);
2513ca95b02SDimitry Andric 
2524ba319b5SDimitry Andric   if (StandardID == &EarlyMachineLICMID)
2533ca95b02SDimitry Andric     return applyDisable(TargetID, DisableMachineLICM);
2543ca95b02SDimitry Andric 
2553ca95b02SDimitry Andric   if (StandardID == &MachineCSEID)
2563ca95b02SDimitry Andric     return applyDisable(TargetID, DisableMachineCSE);
2573ca95b02SDimitry Andric 
2584ba319b5SDimitry Andric   if (StandardID == &MachineLICMID)
2593ca95b02SDimitry Andric     return applyDisable(TargetID, DisablePostRAMachineLICM);
2603ca95b02SDimitry Andric 
2613ca95b02SDimitry Andric   if (StandardID == &MachineSinkingID)
2623ca95b02SDimitry Andric     return applyDisable(TargetID, DisableMachineSink);
2633ca95b02SDimitry Andric 
2644ba319b5SDimitry Andric   if (StandardID == &PostRAMachineSinkingID)
2654ba319b5SDimitry Andric     return applyDisable(TargetID, DisablePostRAMachineSink);
2664ba319b5SDimitry Andric 
2673ca95b02SDimitry Andric   if (StandardID == &MachineCopyPropagationID)
2683ca95b02SDimitry Andric     return applyDisable(TargetID, DisableCopyProp);
2693ca95b02SDimitry Andric 
2703ca95b02SDimitry Andric   return TargetID;
2713ca95b02SDimitry Andric }
2723ca95b02SDimitry Andric 
2733ca95b02SDimitry Andric //===---------------------------------------------------------------------===//
2743ca95b02SDimitry Andric /// TargetPassConfig
2753ca95b02SDimitry Andric //===---------------------------------------------------------------------===//
2763ca95b02SDimitry Andric 
2773ca95b02SDimitry Andric INITIALIZE_PASS(TargetPassConfig, "targetpassconfig",
2783ca95b02SDimitry Andric                 "Target Pass Configuration", false, false)
2793ca95b02SDimitry Andric char TargetPassConfig::ID = 0;
2803ca95b02SDimitry Andric 
2813ca95b02SDimitry Andric namespace {
282a580b014SDimitry Andric 
2833ca95b02SDimitry Andric struct InsertedPass {
2843ca95b02SDimitry Andric   AnalysisID TargetPassID;
2853ca95b02SDimitry Andric   IdentifyingPassPtr InsertedPassID;
2863ca95b02SDimitry Andric   bool VerifyAfter;
2873ca95b02SDimitry Andric   bool PrintAfter;
2883ca95b02SDimitry Andric 
InsertedPass__anon33e883ad0111::InsertedPass2893ca95b02SDimitry Andric   InsertedPass(AnalysisID TargetPassID, IdentifyingPassPtr InsertedPassID,
2903ca95b02SDimitry Andric                bool VerifyAfter, bool PrintAfter)
2913ca95b02SDimitry Andric       : TargetPassID(TargetPassID), InsertedPassID(InsertedPassID),
2923ca95b02SDimitry Andric         VerifyAfter(VerifyAfter), PrintAfter(PrintAfter) {}
2933ca95b02SDimitry Andric 
getInsertedPass__anon33e883ad0111::InsertedPass2943ca95b02SDimitry Andric   Pass *getInsertedPass() const {
2953ca95b02SDimitry Andric     assert(InsertedPassID.isValid() && "Illegal Pass ID!");
2963ca95b02SDimitry Andric     if (InsertedPassID.isInstance())
2973ca95b02SDimitry Andric       return InsertedPassID.getInstance();
2983ca95b02SDimitry Andric     Pass *NP = Pass::createPass(InsertedPassID.getID());
2993ca95b02SDimitry Andric     assert(NP && "Pass ID not registered");
3003ca95b02SDimitry Andric     return NP;
3013ca95b02SDimitry Andric   }
3023ca95b02SDimitry Andric };
303a580b014SDimitry Andric 
304a580b014SDimitry Andric } // end anonymous namespace
3053ca95b02SDimitry Andric 
3063ca95b02SDimitry Andric namespace llvm {
307a580b014SDimitry Andric 
3083ca95b02SDimitry Andric class PassConfigImpl {
3093ca95b02SDimitry Andric public:
3103ca95b02SDimitry Andric   // List of passes explicitly substituted by this target. Normally this is
3113ca95b02SDimitry Andric   // empty, but it is a convenient way to suppress or replace specific passes
3123ca95b02SDimitry Andric   // that are part of a standard pass pipeline without overridding the entire
3133ca95b02SDimitry Andric   // pipeline. This mechanism allows target options to inherit a standard pass's
3143ca95b02SDimitry Andric   // user interface. For example, a target may disable a standard pass by
3153ca95b02SDimitry Andric   // default by substituting a pass ID of zero, and the user may still enable
3163ca95b02SDimitry Andric   // that standard pass with an explicit command line option.
3173ca95b02SDimitry Andric   DenseMap<AnalysisID,IdentifyingPassPtr> TargetPasses;
3183ca95b02SDimitry Andric 
3193ca95b02SDimitry Andric   /// Store the pairs of <AnalysisID, AnalysisID> of which the second pass
3203ca95b02SDimitry Andric   /// is inserted after each instance of the first one.
3213ca95b02SDimitry Andric   SmallVector<InsertedPass, 4> InsertedPasses;
3223ca95b02SDimitry Andric };
323a580b014SDimitry Andric 
324a580b014SDimitry Andric } // end namespace llvm
3253ca95b02SDimitry Andric 
3263ca95b02SDimitry Andric // Out of line virtual method.
~TargetPassConfig()3273ca95b02SDimitry Andric TargetPassConfig::~TargetPassConfig() {
3283ca95b02SDimitry Andric   delete Impl;
3293ca95b02SDimitry Andric }
3303ca95b02SDimitry Andric 
getPassInfo(StringRef PassName)3312cab237bSDimitry Andric static const PassInfo *getPassInfo(StringRef PassName) {
3322cab237bSDimitry Andric   if (PassName.empty())
3332cab237bSDimitry Andric     return nullptr;
3342cab237bSDimitry Andric 
3352cab237bSDimitry Andric   const PassRegistry &PR = *PassRegistry::getPassRegistry();
3362cab237bSDimitry Andric   const PassInfo *PI = PR.getPassInfo(PassName);
3372cab237bSDimitry Andric   if (!PI)
3382cab237bSDimitry Andric     report_fatal_error(Twine('\"') + Twine(PassName) +
3392cab237bSDimitry Andric                        Twine("\" pass is not registered."));
3402cab237bSDimitry Andric   return PI;
3412cab237bSDimitry Andric }
3422cab237bSDimitry Andric 
getPassIDFromName(StringRef PassName)3432cab237bSDimitry Andric static AnalysisID getPassIDFromName(StringRef PassName) {
3442cab237bSDimitry Andric   const PassInfo *PI = getPassInfo(PassName);
3452cab237bSDimitry Andric   return PI ? PI->getTypeInfo() : nullptr;
3462cab237bSDimitry Andric }
3472cab237bSDimitry Andric 
348*b5893f02SDimitry Andric static std::pair<StringRef, unsigned>
getPassNameAndInstanceNum(StringRef PassName)349*b5893f02SDimitry Andric getPassNameAndInstanceNum(StringRef PassName) {
350*b5893f02SDimitry Andric   StringRef Name, InstanceNumStr;
351*b5893f02SDimitry Andric   std::tie(Name, InstanceNumStr) = PassName.split(',');
352*b5893f02SDimitry Andric 
353*b5893f02SDimitry Andric   unsigned InstanceNum = 0;
354*b5893f02SDimitry Andric   if (!InstanceNumStr.empty() && InstanceNumStr.getAsInteger(10, InstanceNum))
355*b5893f02SDimitry Andric     report_fatal_error("invalid pass instance specifier " + PassName);
356*b5893f02SDimitry Andric 
357*b5893f02SDimitry Andric   return std::make_pair(Name, InstanceNum);
358*b5893f02SDimitry Andric }
359*b5893f02SDimitry Andric 
setStartStopPasses()3602cab237bSDimitry Andric void TargetPassConfig::setStartStopPasses() {
361*b5893f02SDimitry Andric   StringRef StartBeforeName;
362*b5893f02SDimitry Andric   std::tie(StartBeforeName, StartBeforeInstanceNum) =
363*b5893f02SDimitry Andric     getPassNameAndInstanceNum(StartBeforeOpt);
364*b5893f02SDimitry Andric 
365*b5893f02SDimitry Andric   StringRef StartAfterName;
366*b5893f02SDimitry Andric   std::tie(StartAfterName, StartAfterInstanceNum) =
367*b5893f02SDimitry Andric     getPassNameAndInstanceNum(StartAfterOpt);
368*b5893f02SDimitry Andric 
369*b5893f02SDimitry Andric   StringRef StopBeforeName;
370*b5893f02SDimitry Andric   std::tie(StopBeforeName, StopBeforeInstanceNum)
371*b5893f02SDimitry Andric     = getPassNameAndInstanceNum(StopBeforeOpt);
372*b5893f02SDimitry Andric 
373*b5893f02SDimitry Andric   StringRef StopAfterName;
374*b5893f02SDimitry Andric   std::tie(StopAfterName, StopAfterInstanceNum)
375*b5893f02SDimitry Andric     = getPassNameAndInstanceNum(StopAfterOpt);
376*b5893f02SDimitry Andric 
377*b5893f02SDimitry Andric   StartBefore = getPassIDFromName(StartBeforeName);
378*b5893f02SDimitry Andric   StartAfter = getPassIDFromName(StartAfterName);
379*b5893f02SDimitry Andric   StopBefore = getPassIDFromName(StopBeforeName);
380*b5893f02SDimitry Andric   StopAfter = getPassIDFromName(StopAfterName);
3812cab237bSDimitry Andric   if (StartBefore && StartAfter)
3822cab237bSDimitry Andric     report_fatal_error(Twine(StartBeforeOptName) + Twine(" and ") +
3832cab237bSDimitry Andric                        Twine(StartAfterOptName) + Twine(" specified!"));
3842cab237bSDimitry Andric   if (StopBefore && StopAfter)
3852cab237bSDimitry Andric     report_fatal_error(Twine(StopBeforeOptName) + Twine(" and ") +
3862cab237bSDimitry Andric                        Twine(StopAfterOptName) + Twine(" specified!"));
3872cab237bSDimitry Andric   Started = (StartAfter == nullptr) && (StartBefore == nullptr);
3882cab237bSDimitry Andric }
3892cab237bSDimitry Andric 
3903ca95b02SDimitry Andric // Out of line constructor provides default values for pass options and
3913ca95b02SDimitry Andric // registers all common codegen passes.
TargetPassConfig(LLVMTargetMachine & TM,PassManagerBase & pm)392f9448bf3SDimitry Andric TargetPassConfig::TargetPassConfig(LLVMTargetMachine &TM, PassManagerBase &pm)
393a580b014SDimitry Andric     : ImmutablePass(ID), PM(&pm), TM(&TM) {
3943ca95b02SDimitry Andric   Impl = new PassConfigImpl();
3953ca95b02SDimitry Andric 
3963ca95b02SDimitry Andric   // Register all target independent codegen passes to activate their PassIDs,
3973ca95b02SDimitry Andric   // including this pass itself.
3983ca95b02SDimitry Andric   initializeCodeGen(*PassRegistry::getPassRegistry());
3993ca95b02SDimitry Andric 
4003ca95b02SDimitry Andric   // Also register alias analysis passes required by codegen passes.
4013ca95b02SDimitry Andric   initializeBasicAAWrapperPassPass(*PassRegistry::getPassRegistry());
4023ca95b02SDimitry Andric   initializeAAResultsWrapperPassPass(*PassRegistry::getPassRegistry());
4033ca95b02SDimitry Andric 
4043ca95b02SDimitry Andric   if (StringRef(PrintMachineInstrs.getValue()).equals(""))
405f9448bf3SDimitry Andric     TM.Options.PrintMachineCode = true;
4067a7e6055SDimitry Andric 
4072cab237bSDimitry Andric   if (EnableIPRA.getNumOccurrences())
4082cab237bSDimitry Andric     TM.Options.EnableIPRA = EnableIPRA;
4092cab237bSDimitry Andric   else {
4102cab237bSDimitry Andric     // If not explicitly specified, use target default.
4112cab237bSDimitry Andric     TM.Options.EnableIPRA = TM.useIPRA();
4122cab237bSDimitry Andric   }
4132cab237bSDimitry Andric 
414f9448bf3SDimitry Andric   if (TM.Options.EnableIPRA)
4157a7e6055SDimitry Andric     setRequiresCodeGenSCCOrder();
4162cab237bSDimitry Andric 
417*b5893f02SDimitry Andric   if (EnableGlobalISelAbort.getNumOccurrences())
418*b5893f02SDimitry Andric     TM.Options.GlobalISelAbort = EnableGlobalISelAbort;
419*b5893f02SDimitry Andric 
4202cab237bSDimitry Andric   setStartStopPasses();
4213ca95b02SDimitry Andric }
4223ca95b02SDimitry Andric 
getOptLevel() const4233ca95b02SDimitry Andric CodeGenOpt::Level TargetPassConfig::getOptLevel() const {
4243ca95b02SDimitry Andric   return TM->getOptLevel();
4253ca95b02SDimitry Andric }
4263ca95b02SDimitry Andric 
4273ca95b02SDimitry Andric /// Insert InsertedPassID pass after TargetPassID.
insertPass(AnalysisID TargetPassID,IdentifyingPassPtr InsertedPassID,bool VerifyAfter,bool PrintAfter)4283ca95b02SDimitry Andric void TargetPassConfig::insertPass(AnalysisID TargetPassID,
4293ca95b02SDimitry Andric                                   IdentifyingPassPtr InsertedPassID,
4303ca95b02SDimitry Andric                                   bool VerifyAfter, bool PrintAfter) {
4313ca95b02SDimitry Andric   assert(((!InsertedPassID.isInstance() &&
4323ca95b02SDimitry Andric            TargetPassID != InsertedPassID.getID()) ||
4333ca95b02SDimitry Andric           (InsertedPassID.isInstance() &&
4343ca95b02SDimitry Andric            TargetPassID != InsertedPassID.getInstance()->getPassID())) &&
4353ca95b02SDimitry Andric          "Insert a pass after itself!");
4363ca95b02SDimitry Andric   Impl->InsertedPasses.emplace_back(TargetPassID, InsertedPassID, VerifyAfter,
4373ca95b02SDimitry Andric                                     PrintAfter);
4383ca95b02SDimitry Andric }
4393ca95b02SDimitry Andric 
4403ca95b02SDimitry Andric /// createPassConfig - Create a pass configuration object to be used by
4413ca95b02SDimitry Andric /// addPassToEmitX methods for generating a pipeline of CodeGen passes.
4423ca95b02SDimitry Andric ///
4433ca95b02SDimitry Andric /// Targets may override this to extend TargetPassConfig.
createPassConfig(PassManagerBase & PM)4443ca95b02SDimitry Andric TargetPassConfig *LLVMTargetMachine::createPassConfig(PassManagerBase &PM) {
445f9448bf3SDimitry Andric   return new TargetPassConfig(*this, PM);
4463ca95b02SDimitry Andric }
4473ca95b02SDimitry Andric 
TargetPassConfig()4483ca95b02SDimitry Andric TargetPassConfig::TargetPassConfig()
449a580b014SDimitry Andric   : ImmutablePass(ID) {
450d8866befSDimitry Andric   report_fatal_error("Trying to construct TargetPassConfig without a target "
451d8866befSDimitry Andric                      "machine. Scheduling a CodeGen pass without a target "
452d8866befSDimitry Andric                      "triple set?");
4533ca95b02SDimitry Andric }
4543ca95b02SDimitry Andric 
willCompleteCodeGenPipeline()455*b5893f02SDimitry Andric bool TargetPassConfig::willCompleteCodeGenPipeline() {
456*b5893f02SDimitry Andric   return StopBeforeOpt.empty() && StopAfterOpt.empty();
457*b5893f02SDimitry Andric }
458*b5893f02SDimitry Andric 
hasLimitedCodeGenPipeline()459*b5893f02SDimitry Andric bool TargetPassConfig::hasLimitedCodeGenPipeline() {
460*b5893f02SDimitry Andric   return !StartBeforeOpt.empty() || !StartAfterOpt.empty() ||
461*b5893f02SDimitry Andric          !willCompleteCodeGenPipeline();
4622cab237bSDimitry Andric }
4632cab237bSDimitry Andric 
4642cab237bSDimitry Andric std::string
getLimitedCodeGenPipelineReason(const char * Separator) const4652cab237bSDimitry Andric TargetPassConfig::getLimitedCodeGenPipelineReason(const char *Separator) const {
4662cab237bSDimitry Andric   if (!hasLimitedCodeGenPipeline())
4672cab237bSDimitry Andric     return std::string();
4682cab237bSDimitry Andric   std::string Res;
4692cab237bSDimitry Andric   static cl::opt<std::string> *PassNames[] = {&StartAfterOpt, &StartBeforeOpt,
4702cab237bSDimitry Andric                                               &StopAfterOpt, &StopBeforeOpt};
4712cab237bSDimitry Andric   static const char *OptNames[] = {StartAfterOptName, StartBeforeOptName,
4722cab237bSDimitry Andric                                    StopAfterOptName, StopBeforeOptName};
4732cab237bSDimitry Andric   bool IsFirst = true;
4742cab237bSDimitry Andric   for (int Idx = 0; Idx < 4; ++Idx)
4752cab237bSDimitry Andric     if (!PassNames[Idx]->empty()) {
4762cab237bSDimitry Andric       if (!IsFirst)
4772cab237bSDimitry Andric         Res += Separator;
4782cab237bSDimitry Andric       IsFirst = false;
4792cab237bSDimitry Andric       Res += OptNames[Idx];
4802cab237bSDimitry Andric     }
4812cab237bSDimitry Andric   return Res;
4822cab237bSDimitry Andric }
4832cab237bSDimitry Andric 
4843ca95b02SDimitry Andric // Helper to verify the analysis is really immutable.
setOpt(bool & Opt,bool Val)4853ca95b02SDimitry Andric void TargetPassConfig::setOpt(bool &Opt, bool Val) {
4863ca95b02SDimitry Andric   assert(!Initialized && "PassConfig is immutable");
4873ca95b02SDimitry Andric   Opt = Val;
4883ca95b02SDimitry Andric }
4893ca95b02SDimitry Andric 
substitutePass(AnalysisID StandardID,IdentifyingPassPtr TargetID)4903ca95b02SDimitry Andric void TargetPassConfig::substitutePass(AnalysisID StandardID,
4913ca95b02SDimitry Andric                                       IdentifyingPassPtr TargetID) {
4923ca95b02SDimitry Andric   Impl->TargetPasses[StandardID] = TargetID;
4933ca95b02SDimitry Andric }
4943ca95b02SDimitry Andric 
getPassSubstitution(AnalysisID ID) const4953ca95b02SDimitry Andric IdentifyingPassPtr TargetPassConfig::getPassSubstitution(AnalysisID ID) const {
4963ca95b02SDimitry Andric   DenseMap<AnalysisID, IdentifyingPassPtr>::const_iterator
4973ca95b02SDimitry Andric     I = Impl->TargetPasses.find(ID);
4983ca95b02SDimitry Andric   if (I == Impl->TargetPasses.end())
4993ca95b02SDimitry Andric     return ID;
5003ca95b02SDimitry Andric   return I->second;
5013ca95b02SDimitry Andric }
5023ca95b02SDimitry Andric 
isPassSubstitutedOrOverridden(AnalysisID ID) const5033ca95b02SDimitry Andric bool TargetPassConfig::isPassSubstitutedOrOverridden(AnalysisID ID) const {
5043ca95b02SDimitry Andric   IdentifyingPassPtr TargetID = getPassSubstitution(ID);
5053ca95b02SDimitry Andric   IdentifyingPassPtr FinalPtr = overridePass(ID, TargetID);
5063ca95b02SDimitry Andric   return !FinalPtr.isValid() || FinalPtr.isInstance() ||
5073ca95b02SDimitry Andric       FinalPtr.getID() != ID;
5083ca95b02SDimitry Andric }
5093ca95b02SDimitry Andric 
5103ca95b02SDimitry Andric /// Add a pass to the PassManager if that pass is supposed to be run.  If the
5113ca95b02SDimitry Andric /// Started/Stopped flags indicate either that the compilation should start at
5123ca95b02SDimitry Andric /// a later pass or that it should stop after an earlier pass, then do not add
5133ca95b02SDimitry Andric /// the pass.  Finally, compare the current pass against the StartAfter
5143ca95b02SDimitry Andric /// and StopAfter options and change the Started/Stopped flags accordingly.
addPass(Pass * P,bool verifyAfter,bool printAfter)5153ca95b02SDimitry Andric void TargetPassConfig::addPass(Pass *P, bool verifyAfter, bool printAfter) {
5163ca95b02SDimitry Andric   assert(!Initialized && "PassConfig is immutable");
5173ca95b02SDimitry Andric 
5183ca95b02SDimitry Andric   // Cache the Pass ID here in case the pass manager finds this pass is
5193ca95b02SDimitry Andric   // redundant with ones already scheduled / available, and deletes it.
5203ca95b02SDimitry Andric   // Fundamentally, once we add the pass to the manager, we no longer own it
5213ca95b02SDimitry Andric   // and shouldn't reference it.
5223ca95b02SDimitry Andric   AnalysisID PassID = P->getPassID();
5233ca95b02SDimitry Andric 
524*b5893f02SDimitry Andric   if (StartBefore == PassID && StartBeforeCount++ == StartBeforeInstanceNum)
5253ca95b02SDimitry Andric     Started = true;
526*b5893f02SDimitry Andric   if (StopBefore == PassID && StopBeforeCount++ == StopBeforeInstanceNum)
527d88c1a5aSDimitry Andric     Stopped = true;
5283ca95b02SDimitry Andric   if (Started && !Stopped) {
5293ca95b02SDimitry Andric     std::string Banner;
5303ca95b02SDimitry Andric     // Construct banner message before PM->add() as that may delete the pass.
5313ca95b02SDimitry Andric     if (AddingMachinePasses && (printAfter || verifyAfter))
5323ca95b02SDimitry Andric       Banner = std::string("After ") + std::string(P->getPassName());
5333ca95b02SDimitry Andric     PM->add(P);
5343ca95b02SDimitry Andric     if (AddingMachinePasses) {
5353ca95b02SDimitry Andric       if (printAfter)
5363ca95b02SDimitry Andric         addPrintPass(Banner);
5373ca95b02SDimitry Andric       if (verifyAfter)
5383ca95b02SDimitry Andric         addVerifyPass(Banner);
5393ca95b02SDimitry Andric     }
5403ca95b02SDimitry Andric 
5413ca95b02SDimitry Andric     // Add the passes after the pass P if there is any.
5423ca95b02SDimitry Andric     for (auto IP : Impl->InsertedPasses) {
5433ca95b02SDimitry Andric       if (IP.TargetPassID == PassID)
5443ca95b02SDimitry Andric         addPass(IP.getInsertedPass(), IP.VerifyAfter, IP.PrintAfter);
5453ca95b02SDimitry Andric     }
5463ca95b02SDimitry Andric   } else {
5473ca95b02SDimitry Andric     delete P;
5483ca95b02SDimitry Andric   }
549*b5893f02SDimitry Andric 
550*b5893f02SDimitry Andric   if (StopAfter == PassID && StopAfterCount++ == StopAfterInstanceNum)
5513ca95b02SDimitry Andric     Stopped = true;
552*b5893f02SDimitry Andric 
553*b5893f02SDimitry Andric   if (StartAfter == PassID && StartAfterCount++ == StartAfterInstanceNum)
5543ca95b02SDimitry Andric     Started = true;
5553ca95b02SDimitry Andric   if (Stopped && !Started)
5563ca95b02SDimitry Andric     report_fatal_error("Cannot stop compilation after pass that is not run");
5573ca95b02SDimitry Andric }
5583ca95b02SDimitry Andric 
5593ca95b02SDimitry Andric /// Add a CodeGen pass at this point in the pipeline after checking for target
5603ca95b02SDimitry Andric /// and command line overrides.
5613ca95b02SDimitry Andric ///
5623ca95b02SDimitry Andric /// addPass cannot return a pointer to the pass instance because is internal the
5633ca95b02SDimitry Andric /// PassManager and the instance we create here may already be freed.
addPass(AnalysisID PassID,bool verifyAfter,bool printAfter)5643ca95b02SDimitry Andric AnalysisID TargetPassConfig::addPass(AnalysisID PassID, bool verifyAfter,
5653ca95b02SDimitry Andric                                      bool printAfter) {
5663ca95b02SDimitry Andric   IdentifyingPassPtr TargetID = getPassSubstitution(PassID);
5673ca95b02SDimitry Andric   IdentifyingPassPtr FinalPtr = overridePass(PassID, TargetID);
5683ca95b02SDimitry Andric   if (!FinalPtr.isValid())
5693ca95b02SDimitry Andric     return nullptr;
5703ca95b02SDimitry Andric 
5713ca95b02SDimitry Andric   Pass *P;
5723ca95b02SDimitry Andric   if (FinalPtr.isInstance())
5733ca95b02SDimitry Andric     P = FinalPtr.getInstance();
5743ca95b02SDimitry Andric   else {
5753ca95b02SDimitry Andric     P = Pass::createPass(FinalPtr.getID());
5763ca95b02SDimitry Andric     if (!P)
5773ca95b02SDimitry Andric       llvm_unreachable("Pass ID not registered");
5783ca95b02SDimitry Andric   }
5793ca95b02SDimitry Andric   AnalysisID FinalID = P->getPassID();
5803ca95b02SDimitry Andric   addPass(P, verifyAfter, printAfter); // Ends the lifetime of P.
5813ca95b02SDimitry Andric 
5823ca95b02SDimitry Andric   return FinalID;
5833ca95b02SDimitry Andric }
5843ca95b02SDimitry Andric 
printAndVerify(const std::string & Banner)5853ca95b02SDimitry Andric void TargetPassConfig::printAndVerify(const std::string &Banner) {
5863ca95b02SDimitry Andric   addPrintPass(Banner);
5873ca95b02SDimitry Andric   addVerifyPass(Banner);
5883ca95b02SDimitry Andric }
5893ca95b02SDimitry Andric 
addPrintPass(const std::string & Banner)5903ca95b02SDimitry Andric void TargetPassConfig::addPrintPass(const std::string &Banner) {
5913ca95b02SDimitry Andric   if (TM->shouldPrintMachineCode())
5923ca95b02SDimitry Andric     PM->add(createMachineFunctionPrinterPass(dbgs(), Banner));
5933ca95b02SDimitry Andric }
5943ca95b02SDimitry Andric 
addVerifyPass(const std::string & Banner)5953ca95b02SDimitry Andric void TargetPassConfig::addVerifyPass(const std::string &Banner) {
596*b5893f02SDimitry Andric   bool Verify = VerifyMachineCode == cl::BOU_TRUE;
597f9448bf3SDimitry Andric #ifdef EXPENSIVE_CHECKS
598f9448bf3SDimitry Andric   if (VerifyMachineCode == cl::BOU_UNSET)
599f9448bf3SDimitry Andric     Verify = TM->isMachineVerifierClean();
600f9448bf3SDimitry Andric #endif
601f9448bf3SDimitry Andric   if (Verify)
6023ca95b02SDimitry Andric     PM->add(createMachineVerifierPass(Banner));
6033ca95b02SDimitry Andric }
6043ca95b02SDimitry Andric 
6053ca95b02SDimitry Andric /// Add common target configurable passes that perform LLVM IR to IR transforms
6063ca95b02SDimitry Andric /// following machine independent optimization.
addIRPasses()6073ca95b02SDimitry Andric void TargetPassConfig::addIRPasses() {
6083ca95b02SDimitry Andric   switch (UseCFLAA) {
6093ca95b02SDimitry Andric   case CFLAAType::Steensgaard:
6103ca95b02SDimitry Andric     addPass(createCFLSteensAAWrapperPass());
6113ca95b02SDimitry Andric     break;
6123ca95b02SDimitry Andric   case CFLAAType::Andersen:
6133ca95b02SDimitry Andric     addPass(createCFLAndersAAWrapperPass());
6143ca95b02SDimitry Andric     break;
6153ca95b02SDimitry Andric   case CFLAAType::Both:
6163ca95b02SDimitry Andric     addPass(createCFLAndersAAWrapperPass());
6173ca95b02SDimitry Andric     addPass(createCFLSteensAAWrapperPass());
6183ca95b02SDimitry Andric     break;
6193ca95b02SDimitry Andric   default:
6203ca95b02SDimitry Andric     break;
6213ca95b02SDimitry Andric   }
6223ca95b02SDimitry Andric 
6233ca95b02SDimitry Andric   // Basic AliasAnalysis support.
6243ca95b02SDimitry Andric   // Add TypeBasedAliasAnalysis before BasicAliasAnalysis so that
6253ca95b02SDimitry Andric   // BasicAliasAnalysis wins if they disagree. This is intended to help
6263ca95b02SDimitry Andric   // support "obvious" type-punning idioms.
6273ca95b02SDimitry Andric   addPass(createTypeBasedAAWrapperPass());
6283ca95b02SDimitry Andric   addPass(createScopedNoAliasAAWrapperPass());
6293ca95b02SDimitry Andric   addPass(createBasicAAWrapperPass());
6303ca95b02SDimitry Andric 
6313ca95b02SDimitry Andric   // Before running any passes, run the verifier to determine if the input
6323ca95b02SDimitry Andric   // coming from the front-end and/or optimizer is valid.
6333ca95b02SDimitry Andric   if (!DisableVerify)
6343ca95b02SDimitry Andric     addPass(createVerifierPass());
6353ca95b02SDimitry Andric 
6363ca95b02SDimitry Andric   // Run loop strength reduction before anything else.
6373ca95b02SDimitry Andric   if (getOptLevel() != CodeGenOpt::None && !DisableLSR) {
6383ca95b02SDimitry Andric     addPass(createLoopStrengthReducePass());
6393ca95b02SDimitry Andric     if (PrintLSR)
6403ca95b02SDimitry Andric       addPass(createPrintFunctionPass(dbgs(), "\n\n*** Code after LSR ***\n"));
6413ca95b02SDimitry Andric   }
6423ca95b02SDimitry Andric 
6432cab237bSDimitry Andric   if (getOptLevel() != CodeGenOpt::None) {
6442cab237bSDimitry Andric     // The MergeICmpsPass tries to create memcmp calls by grouping sequences of
6452cab237bSDimitry Andric     // loads and compares. ExpandMemCmpPass then tries to expand those calls
6462cab237bSDimitry Andric     // into optimally-sized loads and compares. The transforms are enabled by a
6472cab237bSDimitry Andric     // target lowering hook.
6484ba319b5SDimitry Andric     if (!DisableMergeICmps)
6492cab237bSDimitry Andric       addPass(createMergeICmpsPass());
6502cab237bSDimitry Andric     addPass(createExpandMemCmpPass());
6512cab237bSDimitry Andric   }
6522cab237bSDimitry Andric 
6533ca95b02SDimitry Andric   // Run GC lowering passes for builtin collectors
6543ca95b02SDimitry Andric   // TODO: add a pass insertion point here
6553ca95b02SDimitry Andric   addPass(createGCLoweringPass());
6563ca95b02SDimitry Andric   addPass(createShadowStackGCLoweringPass());
6573ca95b02SDimitry Andric 
6583ca95b02SDimitry Andric   // Make sure that no unreachable blocks are instruction selected.
6593ca95b02SDimitry Andric   addPass(createUnreachableBlockEliminationPass());
6603ca95b02SDimitry Andric 
6613ca95b02SDimitry Andric   // Prepare expensive constants for SelectionDAG.
6623ca95b02SDimitry Andric   if (getOptLevel() != CodeGenOpt::None && !DisableConstantHoisting)
6633ca95b02SDimitry Andric     addPass(createConstantHoistingPass());
6643ca95b02SDimitry Andric 
6653ca95b02SDimitry Andric   if (getOptLevel() != CodeGenOpt::None && !DisablePartialLibcallInlining)
6663ca95b02SDimitry Andric     addPass(createPartiallyInlineLibCallsPass());
667d88c1a5aSDimitry Andric 
6682cab237bSDimitry Andric   // Instrument function entry and exit, e.g. with calls to mcount().
6692cab237bSDimitry Andric   addPass(createPostInlineEntryExitInstrumenterPass());
6705517e702SDimitry Andric 
6715517e702SDimitry Andric   // Add scalarization of target's unsupported masked memory intrinsics pass.
6725517e702SDimitry Andric   // the unsupported intrinsic will be replaced with a chain of basic blocks,
6735517e702SDimitry Andric   // that stores/loads element one-by-one if the appropriate mask bit is set.
6745517e702SDimitry Andric   addPass(createScalarizeMaskedMemIntrinPass());
6755517e702SDimitry Andric 
6765517e702SDimitry Andric   // Expand reduction intrinsics into shuffle sequences if the target wants to.
6775517e702SDimitry Andric   addPass(createExpandReductionsPass());
6783ca95b02SDimitry Andric }
6793ca95b02SDimitry Andric 
6803ca95b02SDimitry Andric /// Turn exception handling constructs into something the code generators can
6813ca95b02SDimitry Andric /// handle.
addPassesToHandleExceptions()6823ca95b02SDimitry Andric void TargetPassConfig::addPassesToHandleExceptions() {
683d88c1a5aSDimitry Andric   const MCAsmInfo *MCAI = TM->getMCAsmInfo();
684d88c1a5aSDimitry Andric   assert(MCAI && "No MCAsmInfo");
685d88c1a5aSDimitry Andric   switch (MCAI->getExceptionHandlingType()) {
6863ca95b02SDimitry Andric   case ExceptionHandling::SjLj:
6873ca95b02SDimitry Andric     // SjLj piggy-backs on dwarf for this bit. The cleanups done apply to both
6883ca95b02SDimitry Andric     // Dwarf EH prepare needs to be run after SjLj prepare. Otherwise,
6893ca95b02SDimitry Andric     // catch info can get misplaced when a selector ends up more than one block
6903ca95b02SDimitry Andric     // removed from the parent invoke(s). This could happen when a landing
6913ca95b02SDimitry Andric     // pad is shared by multiple invokes and is also a target of a normal
6923ca95b02SDimitry Andric     // edge from elsewhere.
6933ca95b02SDimitry Andric     addPass(createSjLjEHPreparePass());
694d88c1a5aSDimitry Andric     LLVM_FALLTHROUGH;
6953ca95b02SDimitry Andric   case ExceptionHandling::DwarfCFI:
6963ca95b02SDimitry Andric   case ExceptionHandling::ARM:
697d8866befSDimitry Andric     addPass(createDwarfEHPass());
6983ca95b02SDimitry Andric     break;
6993ca95b02SDimitry Andric   case ExceptionHandling::WinEH:
7003ca95b02SDimitry Andric     // We support using both GCC-style and MSVC-style exceptions on Windows, so
7013ca95b02SDimitry Andric     // add both preparation passes. Each pass will only actually run if it
7023ca95b02SDimitry Andric     // recognizes the personality function.
703d8866befSDimitry Andric     addPass(createWinEHPass());
704d8866befSDimitry Andric     addPass(createDwarfEHPass());
7053ca95b02SDimitry Andric     break;
7064ba319b5SDimitry Andric   case ExceptionHandling::Wasm:
7074ba319b5SDimitry Andric     // Wasm EH uses Windows EH instructions, but it does not need to demote PHIs
7084ba319b5SDimitry Andric     // on catchpads and cleanuppads because it does not outline them into
7094ba319b5SDimitry Andric     // funclets. Catchswitch blocks are not lowered in SelectionDAG, so we
7104ba319b5SDimitry Andric     // should remove PHIs there.
7114ba319b5SDimitry Andric     addPass(createWinEHPass(/*DemoteCatchSwitchPHIOnly=*/false));
7124ba319b5SDimitry Andric     addPass(createWasmEHPass());
7134ba319b5SDimitry Andric     break;
7143ca95b02SDimitry Andric   case ExceptionHandling::None:
7153ca95b02SDimitry Andric     addPass(createLowerInvokePass());
7163ca95b02SDimitry Andric 
7173ca95b02SDimitry Andric     // The lower invoke pass may create unreachable code. Remove it.
7183ca95b02SDimitry Andric     addPass(createUnreachableBlockEliminationPass());
7193ca95b02SDimitry Andric     break;
7203ca95b02SDimitry Andric   }
7213ca95b02SDimitry Andric }
7223ca95b02SDimitry Andric 
7233ca95b02SDimitry Andric /// Add pass to prepare the LLVM IR for code generation. This should be done
7243ca95b02SDimitry Andric /// before exception handling preparation passes.
addCodeGenPrepare()7253ca95b02SDimitry Andric void TargetPassConfig::addCodeGenPrepare() {
7263ca95b02SDimitry Andric   if (getOptLevel() != CodeGenOpt::None && !DisableCGP)
727d8866befSDimitry Andric     addPass(createCodeGenPreparePass());
7283ca95b02SDimitry Andric   addPass(createRewriteSymbolsPass());
7293ca95b02SDimitry Andric }
7303ca95b02SDimitry Andric 
7313ca95b02SDimitry Andric /// Add common passes that perform LLVM IR to IR transforms in preparation for
7323ca95b02SDimitry Andric /// instruction selection.
addISelPrepare()7333ca95b02SDimitry Andric void TargetPassConfig::addISelPrepare() {
7343ca95b02SDimitry Andric   addPreISel();
7353ca95b02SDimitry Andric 
7363ca95b02SDimitry Andric   // Force codegen to run according to the callgraph.
7377a7e6055SDimitry Andric   if (requiresCodeGenSCCOrder())
7383ca95b02SDimitry Andric     addPass(new DummyCGSCCPass);
7393ca95b02SDimitry Andric 
7403ca95b02SDimitry Andric   // Add both the safe stack and the stack protection passes: each of them will
7413ca95b02SDimitry Andric   // only protect functions that have corresponding attributes.
742d8866befSDimitry Andric   addPass(createSafeStackPass());
743d8866befSDimitry Andric   addPass(createStackProtectorPass());
7443ca95b02SDimitry Andric 
7453ca95b02SDimitry Andric   if (PrintISelInput)
7463ca95b02SDimitry Andric     addPass(createPrintFunctionPass(
7473ca95b02SDimitry Andric         dbgs(), "\n\n*** Final LLVM Code input to ISel ***\n"));
7483ca95b02SDimitry Andric 
7493ca95b02SDimitry Andric   // All passes which modify the LLVM IR are now complete; run the verifier
7503ca95b02SDimitry Andric   // to ensure that the IR is valid.
7513ca95b02SDimitry Andric   if (!DisableVerify)
7523ca95b02SDimitry Andric     addPass(createVerifierPass());
7533ca95b02SDimitry Andric }
7543ca95b02SDimitry Andric 
addCoreISelPasses()755db17bf38SDimitry Andric bool TargetPassConfig::addCoreISelPasses() {
7564ba319b5SDimitry Andric   // Enable FastISel with -fast-isel, but allow that to be overridden.
757db17bf38SDimitry Andric   TM->setO0WantsFastISel(EnableFastISelOption != cl::BOU_FALSE);
758*b5893f02SDimitry Andric 
759*b5893f02SDimitry Andric   // Determine an instruction selector.
760*b5893f02SDimitry Andric   enum class SelectorType { SelectionDAG, FastISel, GlobalISel };
761*b5893f02SDimitry Andric   SelectorType Selector;
762*b5893f02SDimitry Andric 
763*b5893f02SDimitry Andric   if (EnableFastISelOption == cl::BOU_TRUE)
764*b5893f02SDimitry Andric     Selector = SelectorType::FastISel;
765*b5893f02SDimitry Andric   else if (EnableGlobalISelOption == cl::BOU_TRUE ||
766*b5893f02SDimitry Andric            (TM->Options.EnableGlobalISel &&
767*b5893f02SDimitry Andric             EnableGlobalISelOption != cl::BOU_FALSE))
768*b5893f02SDimitry Andric     Selector = SelectorType::GlobalISel;
769*b5893f02SDimitry Andric   else if (TM->getOptLevel() == CodeGenOpt::None && TM->getO0WantsFastISel())
770*b5893f02SDimitry Andric     Selector = SelectorType::FastISel;
771*b5893f02SDimitry Andric   else
772*b5893f02SDimitry Andric     Selector = SelectorType::SelectionDAG;
773*b5893f02SDimitry Andric 
774*b5893f02SDimitry Andric   // Set consistently TM->Options.EnableFastISel and EnableGlobalISel.
775*b5893f02SDimitry Andric   if (Selector == SelectorType::FastISel) {
776db17bf38SDimitry Andric     TM->setFastISel(true);
777*b5893f02SDimitry Andric     TM->setGlobalISel(false);
778*b5893f02SDimitry Andric   } else if (Selector == SelectorType::GlobalISel) {
779842d113bSDimitry Andric     TM->setFastISel(false);
780*b5893f02SDimitry Andric     TM->setGlobalISel(true);
781*b5893f02SDimitry Andric   }
782842d113bSDimitry Andric 
783*b5893f02SDimitry Andric   // Add instruction selector passes.
784*b5893f02SDimitry Andric   if (Selector == SelectorType::GlobalISel) {
785*b5893f02SDimitry Andric     SaveAndRestore<bool> SavedAddingMachinePasses(AddingMachinePasses, true);
786db17bf38SDimitry Andric     if (addIRTranslator())
787db17bf38SDimitry Andric       return true;
788db17bf38SDimitry Andric 
789db17bf38SDimitry Andric     addPreLegalizeMachineIR();
790db17bf38SDimitry Andric 
791db17bf38SDimitry Andric     if (addLegalizeMachineIR())
792db17bf38SDimitry Andric       return true;
793db17bf38SDimitry Andric 
794db17bf38SDimitry Andric     // Before running the register bank selector, ask the target if it
795db17bf38SDimitry Andric     // wants to run some passes.
796db17bf38SDimitry Andric     addPreRegBankSelect();
797db17bf38SDimitry Andric 
798db17bf38SDimitry Andric     if (addRegBankSelect())
799db17bf38SDimitry Andric       return true;
800db17bf38SDimitry Andric 
801db17bf38SDimitry Andric     addPreGlobalInstructionSelect();
802db17bf38SDimitry Andric 
803db17bf38SDimitry Andric     if (addGlobalInstructionSelect())
804db17bf38SDimitry Andric       return true;
805db17bf38SDimitry Andric 
806db17bf38SDimitry Andric     // Pass to reset the MachineFunction if the ISel failed.
807db17bf38SDimitry Andric     addPass(createResetMachineFunctionPass(
808db17bf38SDimitry Andric         reportDiagnosticWhenGlobalISelFallback(), isGlobalISelAbortEnabled()));
809db17bf38SDimitry Andric 
810db17bf38SDimitry Andric     // Provide a fallback path when we do not want to abort on
811db17bf38SDimitry Andric     // not-yet-supported input.
812db17bf38SDimitry Andric     if (!isGlobalISelAbortEnabled() && addInstSelector())
813db17bf38SDimitry Andric       return true;
814db17bf38SDimitry Andric 
815db17bf38SDimitry Andric   } else if (addInstSelector())
816db17bf38SDimitry Andric     return true;
817db17bf38SDimitry Andric 
818db17bf38SDimitry Andric   return false;
819db17bf38SDimitry Andric }
820db17bf38SDimitry Andric 
addISelPasses()821db17bf38SDimitry Andric bool TargetPassConfig::addISelPasses() {
8224ba319b5SDimitry Andric   if (TM->useEmulatedTLS())
823db17bf38SDimitry Andric     addPass(createLowerEmuTLSPass());
824db17bf38SDimitry Andric 
825db17bf38SDimitry Andric   addPass(createPreISelIntrinsicLoweringPass());
826db17bf38SDimitry Andric   addPass(createTargetTransformInfoWrapperPass(TM->getTargetIRAnalysis()));
827db17bf38SDimitry Andric   addIRPasses();
828db17bf38SDimitry Andric   addCodeGenPrepare();
829db17bf38SDimitry Andric   addPassesToHandleExceptions();
830db17bf38SDimitry Andric   addISelPrepare();
831db17bf38SDimitry Andric 
832db17bf38SDimitry Andric   return addCoreISelPasses();
833db17bf38SDimitry Andric }
834db17bf38SDimitry Andric 
83560ff8e32SDimitry Andric /// -regalloc=... command line option.
useDefaultRegisterAllocator()83660ff8e32SDimitry Andric static FunctionPass *useDefaultRegisterAllocator() { return nullptr; }
83760ff8e32SDimitry Andric static cl::opt<RegisterRegAlloc::FunctionPassCtor, false,
83860ff8e32SDimitry Andric                RegisterPassParser<RegisterRegAlloc>>
8392cab237bSDimitry Andric     RegAlloc("regalloc", cl::Hidden, cl::init(&useDefaultRegisterAllocator),
84060ff8e32SDimitry Andric              cl::desc("Register allocator to use"));
84160ff8e32SDimitry Andric 
8423ca95b02SDimitry Andric /// Add the complete set of target-independent postISel code generator passes.
8433ca95b02SDimitry Andric ///
8443ca95b02SDimitry Andric /// This can be read as the standard order of major LLVM CodeGen stages. Stages
8453ca95b02SDimitry Andric /// with nontrivial configuration or multiple passes are broken out below in
8463ca95b02SDimitry Andric /// add%Stage routines.
8473ca95b02SDimitry Andric ///
8483ca95b02SDimitry Andric /// Any TargetPassConfig::addXX routine may be overriden by the Target. The
8493ca95b02SDimitry Andric /// addPre/Post methods with empty header implementations allow injecting
8503ca95b02SDimitry Andric /// target-specific fixups just before or after major stages. Additionally,
8513ca95b02SDimitry Andric /// targets have the flexibility to change pass order within a stage by
8523ca95b02SDimitry Andric /// overriding default implementation of add%Stage routines below. Each
8533ca95b02SDimitry Andric /// technique has maintainability tradeoffs because alternate pass orders are
8543ca95b02SDimitry Andric /// not well supported. addPre/Post works better if the target pass is easily
8553ca95b02SDimitry Andric /// tied to a common pass. But if it has subtle dependencies on multiple passes,
8563ca95b02SDimitry Andric /// the target should override the stage instead.
8573ca95b02SDimitry Andric ///
8583ca95b02SDimitry Andric /// TODO: We could use a single addPre/Post(ID) hook to allow pass injection
8593ca95b02SDimitry Andric /// before/after any target-independent pass. But it's currently overkill.
addMachinePasses()8603ca95b02SDimitry Andric void TargetPassConfig::addMachinePasses() {
8613ca95b02SDimitry Andric   AddingMachinePasses = true;
8623ca95b02SDimitry Andric 
8633ca95b02SDimitry Andric   // Insert a machine instr printer pass after the specified pass.
864*b5893f02SDimitry Andric   StringRef PrintMachineInstrsPassName = PrintMachineInstrs.getValue();
865*b5893f02SDimitry Andric   if (!PrintMachineInstrsPassName.equals("") &&
866*b5893f02SDimitry Andric       !PrintMachineInstrsPassName.equals("option-unspecified")) {
867*b5893f02SDimitry Andric     if (const PassInfo *TPI = getPassInfo(PrintMachineInstrsPassName)) {
8683ca95b02SDimitry Andric       const PassRegistry *PR = PassRegistry::getPassRegistry();
8693ca95b02SDimitry Andric       const PassInfo *IPI = PR->getPassInfo(StringRef("machineinstr-printer"));
870*b5893f02SDimitry Andric       assert(IPI && "failed to get \"machineinstr-printer\" PassInfo!");
8713ca95b02SDimitry Andric       const char *TID = (const char *)(TPI->getTypeInfo());
8723ca95b02SDimitry Andric       const char *IID = (const char *)(IPI->getTypeInfo());
8733ca95b02SDimitry Andric       insertPass(TID, IID);
8743ca95b02SDimitry Andric     }
875*b5893f02SDimitry Andric   }
8763ca95b02SDimitry Andric 
8773ca95b02SDimitry Andric   // Print the instruction selected machine code...
8783ca95b02SDimitry Andric   printAndVerify("After Instruction Selection");
8793ca95b02SDimitry Andric 
8803ca95b02SDimitry Andric   // Expand pseudo-instructions emitted by ISel.
8813ca95b02SDimitry Andric   addPass(&ExpandISelPseudosID);
8823ca95b02SDimitry Andric 
8833ca95b02SDimitry Andric   // Add passes that optimize machine instructions in SSA form.
8843ca95b02SDimitry Andric   if (getOptLevel() != CodeGenOpt::None) {
8853ca95b02SDimitry Andric     addMachineSSAOptimization();
8863ca95b02SDimitry Andric   } else {
8873ca95b02SDimitry Andric     // If the target requests it, assign local variables to stack slots relative
8883ca95b02SDimitry Andric     // to one another and simplify frame index references where possible.
8893ca95b02SDimitry Andric     addPass(&LocalStackSlotAllocationID, false);
8903ca95b02SDimitry Andric   }
8913ca95b02SDimitry Andric 
8922cab237bSDimitry Andric   if (TM->Options.EnableIPRA)
8932cab237bSDimitry Andric     addPass(createRegUsageInfoPropPass());
8942cab237bSDimitry Andric 
8953ca95b02SDimitry Andric   // Run pre-ra passes.
8963ca95b02SDimitry Andric   addPreRegAlloc();
8973ca95b02SDimitry Andric 
8983ca95b02SDimitry Andric   // Run register allocation and passes that are tightly coupled with it,
8993ca95b02SDimitry Andric   // including phi elimination and scheduling.
9003ca95b02SDimitry Andric   if (getOptimizeRegAlloc())
9013ca95b02SDimitry Andric     addOptimizedRegAlloc(createRegAllocPass(true));
90260ff8e32SDimitry Andric   else {
90360ff8e32SDimitry Andric     if (RegAlloc != &useDefaultRegisterAllocator &&
90460ff8e32SDimitry Andric         RegAlloc != &createFastRegisterAllocator)
90560ff8e32SDimitry Andric       report_fatal_error("Must use fast (default) register allocator for unoptimized regalloc.");
9063ca95b02SDimitry Andric     addFastRegAlloc(createRegAllocPass(false));
90760ff8e32SDimitry Andric   }
9083ca95b02SDimitry Andric 
9093ca95b02SDimitry Andric   // Run post-ra passes.
9103ca95b02SDimitry Andric   addPostRegAlloc();
9113ca95b02SDimitry Andric 
9123ca95b02SDimitry Andric   // Insert prolog/epilog code.  Eliminate abstract frame index references...
9134ba319b5SDimitry Andric   if (getOptLevel() != CodeGenOpt::None) {
9144ba319b5SDimitry Andric     addPass(&PostRAMachineSinkingID);
9153ca95b02SDimitry Andric     addPass(&ShrinkWrapID);
9164ba319b5SDimitry Andric   }
9173ca95b02SDimitry Andric 
9183ca95b02SDimitry Andric   // Prolog/Epilog inserter needs a TargetMachine to instantiate. But only
9193ca95b02SDimitry Andric   // do so if it hasn't been disabled, substituted, or overridden.
9203ca95b02SDimitry Andric   if (!isPassSubstitutedOrOverridden(&PrologEpilogCodeInserterID))
921d8866befSDimitry Andric       addPass(createPrologEpilogInserterPass());
9223ca95b02SDimitry Andric 
9233ca95b02SDimitry Andric   /// Add passes that optimize machine instructions after register allocation.
9243ca95b02SDimitry Andric   if (getOptLevel() != CodeGenOpt::None)
9253ca95b02SDimitry Andric     addMachineLateOptimization();
9263ca95b02SDimitry Andric 
9273ca95b02SDimitry Andric   // Expand pseudo instructions before second scheduling pass.
9283ca95b02SDimitry Andric   addPass(&ExpandPostRAPseudosID);
9293ca95b02SDimitry Andric 
9303ca95b02SDimitry Andric   // Run pre-sched2 passes.
9313ca95b02SDimitry Andric   addPreSched2();
9323ca95b02SDimitry Andric 
9333ca95b02SDimitry Andric   if (EnableImplicitNullChecks)
9343ca95b02SDimitry Andric     addPass(&ImplicitNullChecksID);
9353ca95b02SDimitry Andric 
9363ca95b02SDimitry Andric   // Second pass scheduler.
9373ca95b02SDimitry Andric   // Let Target optionally insert this pass by itself at some other
9383ca95b02SDimitry Andric   // point.
9393ca95b02SDimitry Andric   if (getOptLevel() != CodeGenOpt::None &&
9403ca95b02SDimitry Andric       !TM->targetSchedulesPostRAScheduling()) {
9413ca95b02SDimitry Andric     if (MISchedPostRA)
9423ca95b02SDimitry Andric       addPass(&PostMachineSchedulerID);
9433ca95b02SDimitry Andric     else
9443ca95b02SDimitry Andric       addPass(&PostRASchedulerID);
9453ca95b02SDimitry Andric   }
9463ca95b02SDimitry Andric 
9473ca95b02SDimitry Andric   // GC
9483ca95b02SDimitry Andric   if (addGCPasses()) {
9493ca95b02SDimitry Andric     if (PrintGCInfo)
9503ca95b02SDimitry Andric       addPass(createGCInfoPrinter(dbgs()), false, false);
9513ca95b02SDimitry Andric   }
9523ca95b02SDimitry Andric 
9533ca95b02SDimitry Andric   // Basic block placement.
9543ca95b02SDimitry Andric   if (getOptLevel() != CodeGenOpt::None)
9553ca95b02SDimitry Andric     addBlockPlacement();
9563ca95b02SDimitry Andric 
9573ca95b02SDimitry Andric   addPreEmitPass();
9583ca95b02SDimitry Andric 
9593ca95b02SDimitry Andric   if (TM->Options.EnableIPRA)
9603ca95b02SDimitry Andric     // Collect register usage information and produce a register mask of
9613ca95b02SDimitry Andric     // clobbered registers, to be used to optimize call sites.
9623ca95b02SDimitry Andric     addPass(createRegUsageInfoCollector());
9633ca95b02SDimitry Andric 
9643ca95b02SDimitry Andric   addPass(&FuncletLayoutID, false);
9653ca95b02SDimitry Andric 
9663ca95b02SDimitry Andric   addPass(&StackMapLivenessID, false);
9673ca95b02SDimitry Andric   addPass(&LiveDebugValuesID, false);
9683ca95b02SDimitry Andric 
9697a7e6055SDimitry Andric   // Insert before XRay Instrumentation.
9707a7e6055SDimitry Andric   addPass(&FEntryInserterID, false);
9717a7e6055SDimitry Andric 
9723ca95b02SDimitry Andric   addPass(&XRayInstrumentationID, false);
9733ca95b02SDimitry Andric   addPass(&PatchableFunctionID, false);
9743ca95b02SDimitry Andric 
9754ba319b5SDimitry Andric   if (TM->Options.EnableMachineOutliner && getOptLevel() != CodeGenOpt::None &&
9764ba319b5SDimitry Andric       EnableMachineOutliner != NeverOutline) {
9774ba319b5SDimitry Andric     bool RunOnAllFunctions = (EnableMachineOutliner == AlwaysOutline);
9784ba319b5SDimitry Andric     bool AddOutliner = RunOnAllFunctions ||
9794ba319b5SDimitry Andric                        TM->Options.SupportsDefaultOutlining;
9804ba319b5SDimitry Andric     if (AddOutliner)
9814ba319b5SDimitry Andric       addPass(createMachineOutlinerPass(RunOnAllFunctions));
9824ba319b5SDimitry Andric   }
9837a7e6055SDimitry Andric 
98407577dfeSDimitry Andric   // Add passes that directly emit MI after all other MI passes.
98507577dfeSDimitry Andric   addPreEmitPass2();
98607577dfeSDimitry Andric 
9873ca95b02SDimitry Andric   AddingMachinePasses = false;
9883ca95b02SDimitry Andric }
9893ca95b02SDimitry Andric 
9903ca95b02SDimitry Andric /// Add passes that optimize machine instructions in SSA form.
addMachineSSAOptimization()9913ca95b02SDimitry Andric void TargetPassConfig::addMachineSSAOptimization() {
9923ca95b02SDimitry Andric   // Pre-ra tail duplication.
9933ca95b02SDimitry Andric   addPass(&EarlyTailDuplicateID);
9943ca95b02SDimitry Andric 
9953ca95b02SDimitry Andric   // Optimize PHIs before DCE: removing dead PHI cycles may make more
9963ca95b02SDimitry Andric   // instructions dead.
9973ca95b02SDimitry Andric   addPass(&OptimizePHIsID, false);
9983ca95b02SDimitry Andric 
9993ca95b02SDimitry Andric   // This pass merges large allocas. StackSlotColoring is a different pass
10003ca95b02SDimitry Andric   // which merges spill slots.
10013ca95b02SDimitry Andric   addPass(&StackColoringID, false);
10023ca95b02SDimitry Andric 
10033ca95b02SDimitry Andric   // If the target requests it, assign local variables to stack slots relative
10043ca95b02SDimitry Andric   // to one another and simplify frame index references where possible.
10053ca95b02SDimitry Andric   addPass(&LocalStackSlotAllocationID, false);
10063ca95b02SDimitry Andric 
10073ca95b02SDimitry Andric   // With optimization, dead code should already be eliminated. However
10083ca95b02SDimitry Andric   // there is one known exception: lowered code for arguments that are only
10093ca95b02SDimitry Andric   // used by tail calls, where the tail calls reuse the incoming stack
10103ca95b02SDimitry Andric   // arguments directly (see t11 in test/CodeGen/X86/sibcall.ll).
10113ca95b02SDimitry Andric   addPass(&DeadMachineInstructionElimID);
10123ca95b02SDimitry Andric 
10133ca95b02SDimitry Andric   // Allow targets to insert passes that improve instruction level parallelism,
10143ca95b02SDimitry Andric   // like if-conversion. Such passes will typically need dominator trees and
10153ca95b02SDimitry Andric   // loop info, just like LICM and CSE below.
10163ca95b02SDimitry Andric   addILPOpts();
10173ca95b02SDimitry Andric 
10184ba319b5SDimitry Andric   addPass(&EarlyMachineLICMID, false);
10193ca95b02SDimitry Andric   addPass(&MachineCSEID, false);
10207a7e6055SDimitry Andric 
10213ca95b02SDimitry Andric   addPass(&MachineSinkingID);
10223ca95b02SDimitry Andric 
10233ca95b02SDimitry Andric   addPass(&PeepholeOptimizerID);
10243ca95b02SDimitry Andric   // Clean-up the dead code that may have been generated by peephole
10253ca95b02SDimitry Andric   // rewriting.
10263ca95b02SDimitry Andric   addPass(&DeadMachineInstructionElimID);
10273ca95b02SDimitry Andric }
10283ca95b02SDimitry Andric 
10293ca95b02SDimitry Andric //===---------------------------------------------------------------------===//
10303ca95b02SDimitry Andric /// Register Allocation Pass Configuration
10313ca95b02SDimitry Andric //===---------------------------------------------------------------------===//
10323ca95b02SDimitry Andric 
getOptimizeRegAlloc() const10333ca95b02SDimitry Andric bool TargetPassConfig::getOptimizeRegAlloc() const {
10343ca95b02SDimitry Andric   switch (OptimizeRegAlloc) {
10353ca95b02SDimitry Andric   case cl::BOU_UNSET: return getOptLevel() != CodeGenOpt::None;
10363ca95b02SDimitry Andric   case cl::BOU_TRUE:  return true;
10373ca95b02SDimitry Andric   case cl::BOU_FALSE: return false;
10383ca95b02SDimitry Andric   }
10393ca95b02SDimitry Andric   llvm_unreachable("Invalid optimize-regalloc state");
10403ca95b02SDimitry Andric }
10413ca95b02SDimitry Andric 
10423ca95b02SDimitry Andric /// RegisterRegAlloc's global Registry tracks allocator registration.
1043*b5893f02SDimitry Andric MachinePassRegistry<RegisterRegAlloc::FunctionPassCtor>
1044*b5893f02SDimitry Andric     RegisterRegAlloc::Registry;
10453ca95b02SDimitry Andric 
10463ca95b02SDimitry Andric /// A dummy default pass factory indicates whether the register allocator is
10473ca95b02SDimitry Andric /// overridden on the command line.
10487a7e6055SDimitry Andric static llvm::once_flag InitializeDefaultRegisterAllocatorFlag;
104960ff8e32SDimitry Andric 
10503ca95b02SDimitry Andric static RegisterRegAlloc
10513ca95b02SDimitry Andric defaultRegAlloc("default",
10523ca95b02SDimitry Andric                 "pick register allocator based on -O option",
10533ca95b02SDimitry Andric                 useDefaultRegisterAllocator);
10543ca95b02SDimitry Andric 
initializeDefaultRegisterAllocatorOnce()10553ca95b02SDimitry Andric static void initializeDefaultRegisterAllocatorOnce() {
10563ca95b02SDimitry Andric   RegisterRegAlloc::FunctionPassCtor Ctor = RegisterRegAlloc::getDefault();
10573ca95b02SDimitry Andric 
10583ca95b02SDimitry Andric   if (!Ctor) {
10593ca95b02SDimitry Andric     Ctor = RegAlloc;
10603ca95b02SDimitry Andric     RegisterRegAlloc::setDefault(RegAlloc);
10613ca95b02SDimitry Andric   }
10623ca95b02SDimitry Andric }
10633ca95b02SDimitry Andric 
10643ca95b02SDimitry Andric /// Instantiate the default register allocator pass for this target for either
10653ca95b02SDimitry Andric /// the optimized or unoptimized allocation path. This will be added to the pass
10663ca95b02SDimitry Andric /// manager by addFastRegAlloc in the unoptimized case or addOptimizedRegAlloc
10673ca95b02SDimitry Andric /// in the optimized case.
10683ca95b02SDimitry Andric ///
10693ca95b02SDimitry Andric /// A target that uses the standard regalloc pass order for fast or optimized
10703ca95b02SDimitry Andric /// allocation may still override this for per-target regalloc
10713ca95b02SDimitry Andric /// selection. But -regalloc=... always takes precedence.
createTargetRegisterAllocator(bool Optimized)10723ca95b02SDimitry Andric FunctionPass *TargetPassConfig::createTargetRegisterAllocator(bool Optimized) {
10733ca95b02SDimitry Andric   if (Optimized)
10743ca95b02SDimitry Andric     return createGreedyRegisterAllocator();
10753ca95b02SDimitry Andric   else
10763ca95b02SDimitry Andric     return createFastRegisterAllocator();
10773ca95b02SDimitry Andric }
10783ca95b02SDimitry Andric 
10793ca95b02SDimitry Andric /// Find and instantiate the register allocation pass requested by this target
10803ca95b02SDimitry Andric /// at the current optimization level.  Different register allocators are
10813ca95b02SDimitry Andric /// defined as separate passes because they may require different analysis.
10823ca95b02SDimitry Andric ///
10833ca95b02SDimitry Andric /// This helper ensures that the regalloc= option is always available,
10843ca95b02SDimitry Andric /// even for targets that override the default allocator.
10853ca95b02SDimitry Andric ///
10863ca95b02SDimitry Andric /// FIXME: When MachinePassRegistry register pass IDs instead of function ptrs,
10873ca95b02SDimitry Andric /// this can be folded into addPass.
createRegAllocPass(bool Optimized)10883ca95b02SDimitry Andric FunctionPass *TargetPassConfig::createRegAllocPass(bool Optimized) {
10893ca95b02SDimitry Andric   // Initialize the global default.
10903ca95b02SDimitry Andric   llvm::call_once(InitializeDefaultRegisterAllocatorFlag,
10913ca95b02SDimitry Andric                   initializeDefaultRegisterAllocatorOnce);
10923ca95b02SDimitry Andric 
10933ca95b02SDimitry Andric   RegisterRegAlloc::FunctionPassCtor Ctor = RegisterRegAlloc::getDefault();
10943ca95b02SDimitry Andric   if (Ctor != useDefaultRegisterAllocator)
10953ca95b02SDimitry Andric     return Ctor();
10963ca95b02SDimitry Andric 
10973ca95b02SDimitry Andric   // With no -regalloc= override, ask the target for a regalloc pass.
10983ca95b02SDimitry Andric   return createTargetRegisterAllocator(Optimized);
10993ca95b02SDimitry Andric }
11003ca95b02SDimitry Andric 
11013ca95b02SDimitry Andric /// Return true if the default global register allocator is in use and
11023ca95b02SDimitry Andric /// has not be overriden on the command line with '-regalloc=...'
usingDefaultRegAlloc() const11033ca95b02SDimitry Andric bool TargetPassConfig::usingDefaultRegAlloc() const {
11043ca95b02SDimitry Andric   return RegAlloc.getNumOccurrences() == 0;
11053ca95b02SDimitry Andric }
11063ca95b02SDimitry Andric 
11073ca95b02SDimitry Andric /// Add the minimum set of target-independent passes that are required for
11083ca95b02SDimitry Andric /// register allocation. No coalescing or scheduling.
addFastRegAlloc(FunctionPass * RegAllocPass)11093ca95b02SDimitry Andric void TargetPassConfig::addFastRegAlloc(FunctionPass *RegAllocPass) {
11103ca95b02SDimitry Andric   addPass(&PHIEliminationID, false);
11113ca95b02SDimitry Andric   addPass(&TwoAddressInstructionPassID, false);
11123ca95b02SDimitry Andric 
11133ca95b02SDimitry Andric   if (RegAllocPass)
11143ca95b02SDimitry Andric     addPass(RegAllocPass);
11153ca95b02SDimitry Andric }
11163ca95b02SDimitry Andric 
11173ca95b02SDimitry Andric /// Add standard target-independent passes that are tightly coupled with
11183ca95b02SDimitry Andric /// optimized register allocation, including coalescing, machine instruction
11193ca95b02SDimitry Andric /// scheduling, and register allocation itself.
addOptimizedRegAlloc(FunctionPass * RegAllocPass)11203ca95b02SDimitry Andric void TargetPassConfig::addOptimizedRegAlloc(FunctionPass *RegAllocPass) {
11213ca95b02SDimitry Andric   addPass(&DetectDeadLanesID, false);
11223ca95b02SDimitry Andric 
11233ca95b02SDimitry Andric   addPass(&ProcessImplicitDefsID, false);
11243ca95b02SDimitry Andric 
11253ca95b02SDimitry Andric   // LiveVariables currently requires pure SSA form.
11263ca95b02SDimitry Andric   //
11273ca95b02SDimitry Andric   // FIXME: Once TwoAddressInstruction pass no longer uses kill flags,
11283ca95b02SDimitry Andric   // LiveVariables can be removed completely, and LiveIntervals can be directly
11293ca95b02SDimitry Andric   // computed. (We still either need to regenerate kill flags after regalloc, or
11303ca95b02SDimitry Andric   // preferably fix the scavenger to not depend on them).
11313ca95b02SDimitry Andric   addPass(&LiveVariablesID, false);
11323ca95b02SDimitry Andric 
11333ca95b02SDimitry Andric   // Edge splitting is smarter with machine loop info.
11343ca95b02SDimitry Andric   addPass(&MachineLoopInfoID, false);
11353ca95b02SDimitry Andric   addPass(&PHIEliminationID, false);
11363ca95b02SDimitry Andric 
11373ca95b02SDimitry Andric   // Eventually, we want to run LiveIntervals before PHI elimination.
11383ca95b02SDimitry Andric   if (EarlyLiveIntervals)
11393ca95b02SDimitry Andric     addPass(&LiveIntervalsID, false);
11403ca95b02SDimitry Andric 
11413ca95b02SDimitry Andric   addPass(&TwoAddressInstructionPassID, false);
11423ca95b02SDimitry Andric   addPass(&RegisterCoalescerID);
11433ca95b02SDimitry Andric 
11443ca95b02SDimitry Andric   // The machine scheduler may accidentally create disconnected components
11453ca95b02SDimitry Andric   // when moving subregister definitions around, avoid this by splitting them to
11463ca95b02SDimitry Andric   // separate vregs before. Splitting can also improve reg. allocation quality.
11473ca95b02SDimitry Andric   addPass(&RenameIndependentSubregsID);
11483ca95b02SDimitry Andric 
11493ca95b02SDimitry Andric   // PreRA instruction scheduling.
11503ca95b02SDimitry Andric   addPass(&MachineSchedulerID);
11513ca95b02SDimitry Andric 
11523ca95b02SDimitry Andric   if (RegAllocPass) {
11533ca95b02SDimitry Andric     // Add the selected register allocation pass.
11543ca95b02SDimitry Andric     addPass(RegAllocPass);
11553ca95b02SDimitry Andric 
11563ca95b02SDimitry Andric     // Allow targets to change the register assignments before rewriting.
11573ca95b02SDimitry Andric     addPreRewrite();
11583ca95b02SDimitry Andric 
11593ca95b02SDimitry Andric     // Finally rewrite virtual registers.
11603ca95b02SDimitry Andric     addPass(&VirtRegRewriterID);
11613ca95b02SDimitry Andric 
11623ca95b02SDimitry Andric     // Perform stack slot coloring and post-ra machine LICM.
11633ca95b02SDimitry Andric     //
11643ca95b02SDimitry Andric     // FIXME: Re-enable coloring with register when it's capable of adding
11653ca95b02SDimitry Andric     // kill markers.
11663ca95b02SDimitry Andric     addPass(&StackSlotColoringID);
11673ca95b02SDimitry Andric 
11684ba319b5SDimitry Andric     // Copy propagate to forward register uses and try to eliminate COPYs that
11694ba319b5SDimitry Andric     // were not coalesced.
11704ba319b5SDimitry Andric     addPass(&MachineCopyPropagationID);
11714ba319b5SDimitry Andric 
11723ca95b02SDimitry Andric     // Run post-ra machine LICM to hoist reloads / remats.
11733ca95b02SDimitry Andric     //
11743ca95b02SDimitry Andric     // FIXME: can this move into MachineLateOptimization?
11754ba319b5SDimitry Andric     addPass(&MachineLICMID);
11763ca95b02SDimitry Andric   }
11773ca95b02SDimitry Andric }
11783ca95b02SDimitry Andric 
11793ca95b02SDimitry Andric //===---------------------------------------------------------------------===//
11803ca95b02SDimitry Andric /// Post RegAlloc Pass Configuration
11813ca95b02SDimitry Andric //===---------------------------------------------------------------------===//
11823ca95b02SDimitry Andric 
11833ca95b02SDimitry Andric /// Add passes that optimize machine instructions after register allocation.
addMachineLateOptimization()11843ca95b02SDimitry Andric void TargetPassConfig::addMachineLateOptimization() {
11853ca95b02SDimitry Andric   // Branch folding must be run after regalloc and prolog/epilog insertion.
11863ca95b02SDimitry Andric   addPass(&BranchFolderPassID);
11873ca95b02SDimitry Andric 
11883ca95b02SDimitry Andric   // Tail duplication.
11893ca95b02SDimitry Andric   // Note that duplicating tail just increases code size and degrades
11903ca95b02SDimitry Andric   // performance for targets that require Structured Control Flow.
11913ca95b02SDimitry Andric   // In addition it can also make CFG irreducible. Thus we disable it.
11923ca95b02SDimitry Andric   if (!TM->requiresStructuredCFG())
11933ca95b02SDimitry Andric     addPass(&TailDuplicateID);
11943ca95b02SDimitry Andric 
11953ca95b02SDimitry Andric   // Copy propagation.
11963ca95b02SDimitry Andric   addPass(&MachineCopyPropagationID);
11973ca95b02SDimitry Andric }
11983ca95b02SDimitry Andric 
11993ca95b02SDimitry Andric /// Add standard GC passes.
addGCPasses()12003ca95b02SDimitry Andric bool TargetPassConfig::addGCPasses() {
12013ca95b02SDimitry Andric   addPass(&GCMachineCodeAnalysisID, false);
12023ca95b02SDimitry Andric   return true;
12033ca95b02SDimitry Andric }
12043ca95b02SDimitry Andric 
12053ca95b02SDimitry Andric /// Add standard basic block placement passes.
addBlockPlacement()12063ca95b02SDimitry Andric void TargetPassConfig::addBlockPlacement() {
12073ca95b02SDimitry Andric   if (addPass(&MachineBlockPlacementID)) {
12083ca95b02SDimitry Andric     // Run a separate pass to collect block placement statistics.
12093ca95b02SDimitry Andric     if (EnableBlockPlacementStats)
12103ca95b02SDimitry Andric       addPass(&MachineBlockPlacementStatsID);
12113ca95b02SDimitry Andric   }
12123ca95b02SDimitry Andric }
1213d88c1a5aSDimitry Andric 
1214d88c1a5aSDimitry Andric //===---------------------------------------------------------------------===//
1215d88c1a5aSDimitry Andric /// GlobalISel Configuration
1216d88c1a5aSDimitry Andric //===---------------------------------------------------------------------===//
isGlobalISelAbortEnabled() const1217d88c1a5aSDimitry Andric bool TargetPassConfig::isGlobalISelAbortEnabled() const {
1218*b5893f02SDimitry Andric   return TM->Options.GlobalISelAbort == GlobalISelAbortMode::Enable;
1219d88c1a5aSDimitry Andric }
1220d88c1a5aSDimitry Andric 
reportDiagnosticWhenGlobalISelFallback() const1221d88c1a5aSDimitry Andric bool TargetPassConfig::reportDiagnosticWhenGlobalISelFallback() const {
1222*b5893f02SDimitry Andric   return TM->Options.GlobalISelAbort == GlobalISelAbortMode::DisableWithDiag;
1223d88c1a5aSDimitry Andric }
1224