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