xref: /freebsd/contrib/llvm-project/llvm/include/llvm/CodeGen/TargetPassConfig.h (revision 7a6dacaca14b62ca4b74406814becb87a3fefac0)
10b57cec5SDimitry Andric //===- TargetPassConfig.h - Code Generation pass options --------*- C++ -*-===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
8fe6060f1SDimitry Andric /// \file
90b57cec5SDimitry Andric /// Target-Independent Code Generator Pass Configuration Options pass.
10fe6060f1SDimitry Andric ///
110b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
120b57cec5SDimitry Andric 
130b57cec5SDimitry Andric #ifndef LLVM_CODEGEN_TARGETPASSCONFIG_H
140b57cec5SDimitry Andric #define LLVM_CODEGEN_TARGETPASSCONFIG_H
150b57cec5SDimitry Andric 
160b57cec5SDimitry Andric #include "llvm/Pass.h"
170b57cec5SDimitry Andric #include "llvm/Support/CodeGen.h"
18*7a6dacacSDimitry Andric #include "llvm/Support/Error.h"
190b57cec5SDimitry Andric #include <cassert>
200b57cec5SDimitry Andric #include <string>
210b57cec5SDimitry Andric 
220b57cec5SDimitry Andric namespace llvm {
230b57cec5SDimitry Andric 
240b57cec5SDimitry Andric class LLVMTargetMachine;
250b57cec5SDimitry Andric struct MachineSchedContext;
260b57cec5SDimitry Andric class PassConfigImpl;
270b57cec5SDimitry Andric class ScheduleDAGInstrs;
280b57cec5SDimitry Andric class CSEConfigBase;
29e8d8bef9SDimitry Andric class PassInstrumentationCallbacks;
300b57cec5SDimitry Andric 
310b57cec5SDimitry Andric // The old pass manager infrastructure is hidden in a legacy namespace now.
320b57cec5SDimitry Andric namespace legacy {
330b57cec5SDimitry Andric 
340b57cec5SDimitry Andric class PassManagerBase;
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric } // end namespace legacy
370b57cec5SDimitry Andric 
380b57cec5SDimitry Andric using legacy::PassManagerBase;
390b57cec5SDimitry Andric 
400b57cec5SDimitry Andric /// Discriminated union of Pass ID types.
410b57cec5SDimitry Andric ///
420b57cec5SDimitry Andric /// The PassConfig API prefers dealing with IDs because they are safer and more
430b57cec5SDimitry Andric /// efficient. IDs decouple configuration from instantiation. This way, when a
440b57cec5SDimitry Andric /// pass is overriden, it isn't unnecessarily instantiated. It is also unsafe to
450b57cec5SDimitry Andric /// refer to a Pass pointer after adding it to a pass manager, which deletes
460b57cec5SDimitry Andric /// redundant pass instances.
470b57cec5SDimitry Andric ///
480b57cec5SDimitry Andric /// However, it is convient to directly instantiate target passes with
490b57cec5SDimitry Andric /// non-default ctors. These often don't have a registered PassInfo. Rather than
500b57cec5SDimitry Andric /// force all target passes to implement the pass registry boilerplate, allow
510b57cec5SDimitry Andric /// the PassConfig API to handle either type.
520b57cec5SDimitry Andric ///
530b57cec5SDimitry Andric /// AnalysisID is sadly char*, so PointerIntPair won't work.
540b57cec5SDimitry Andric class IdentifyingPassPtr {
550b57cec5SDimitry Andric   union {
560b57cec5SDimitry Andric     AnalysisID ID;
570b57cec5SDimitry Andric     Pass *P;
580b57cec5SDimitry Andric   };
590b57cec5SDimitry Andric   bool IsInstance = false;
600b57cec5SDimitry Andric 
610b57cec5SDimitry Andric public:
620b57cec5SDimitry Andric   IdentifyingPassPtr() : P(nullptr) {}
630b57cec5SDimitry Andric   IdentifyingPassPtr(AnalysisID IDPtr) : ID(IDPtr) {}
640b57cec5SDimitry Andric   IdentifyingPassPtr(Pass *InstancePtr) : P(InstancePtr), IsInstance(true) {}
650b57cec5SDimitry Andric 
660b57cec5SDimitry Andric   bool isValid() const { return P; }
670b57cec5SDimitry Andric   bool isInstance() const { return IsInstance; }
680b57cec5SDimitry Andric 
690b57cec5SDimitry Andric   AnalysisID getID() const {
700b57cec5SDimitry Andric     assert(!IsInstance && "Not a Pass ID");
710b57cec5SDimitry Andric     return ID;
720b57cec5SDimitry Andric   }
730b57cec5SDimitry Andric 
740b57cec5SDimitry Andric   Pass *getInstance() const {
750b57cec5SDimitry Andric     assert(IsInstance && "Not a Pass Instance");
760b57cec5SDimitry Andric     return P;
770b57cec5SDimitry Andric   }
780b57cec5SDimitry Andric };
790b57cec5SDimitry Andric 
800b57cec5SDimitry Andric 
810b57cec5SDimitry Andric /// Target-Independent Code Generator Pass Configuration Options.
820b57cec5SDimitry Andric ///
830b57cec5SDimitry Andric /// This is an ImmutablePass solely for the purpose of exposing CodeGen options
840b57cec5SDimitry Andric /// to the internals of other CodeGen passes.
850b57cec5SDimitry Andric class TargetPassConfig : public ImmutablePass {
860b57cec5SDimitry Andric private:
870b57cec5SDimitry Andric   PassManagerBase *PM = nullptr;
880b57cec5SDimitry Andric   AnalysisID StartBefore = nullptr;
890b57cec5SDimitry Andric   AnalysisID StartAfter = nullptr;
900b57cec5SDimitry Andric   AnalysisID StopBefore = nullptr;
910b57cec5SDimitry Andric   AnalysisID StopAfter = nullptr;
920b57cec5SDimitry Andric 
930b57cec5SDimitry Andric   unsigned StartBeforeInstanceNum = 0;
940b57cec5SDimitry Andric   unsigned StartBeforeCount = 0;
950b57cec5SDimitry Andric 
960b57cec5SDimitry Andric   unsigned StartAfterInstanceNum = 0;
970b57cec5SDimitry Andric   unsigned StartAfterCount = 0;
980b57cec5SDimitry Andric 
990b57cec5SDimitry Andric   unsigned StopBeforeInstanceNum = 0;
1000b57cec5SDimitry Andric   unsigned StopBeforeCount = 0;
1010b57cec5SDimitry Andric 
1020b57cec5SDimitry Andric   unsigned StopAfterInstanceNum = 0;
1030b57cec5SDimitry Andric   unsigned StopAfterCount = 0;
1040b57cec5SDimitry Andric 
1050b57cec5SDimitry Andric   bool Started = true;
1060b57cec5SDimitry Andric   bool Stopped = false;
1070b57cec5SDimitry Andric   bool AddingMachinePasses = false;
1085ffd83dbSDimitry Andric   bool DebugifyIsSafe = true;
1090b57cec5SDimitry Andric 
1100b57cec5SDimitry Andric   /// Set the StartAfter, StartBefore and StopAfter passes to allow running only
1110b57cec5SDimitry Andric   /// a portion of the normal code-gen pass sequence.
1120b57cec5SDimitry Andric   ///
1130b57cec5SDimitry Andric   /// If the StartAfter and StartBefore pass ID is zero, then compilation will
1140b57cec5SDimitry Andric   /// begin at the normal point; otherwise, clear the Started flag to indicate
1150b57cec5SDimitry Andric   /// that passes should not be added until the starting pass is seen.  If the
1160b57cec5SDimitry Andric   /// Stop pass ID is zero, then compilation will continue to the end.
1170b57cec5SDimitry Andric   ///
1180b57cec5SDimitry Andric   /// This function expects that at least one of the StartAfter or the
1190b57cec5SDimitry Andric   /// StartBefore pass IDs is null.
1200b57cec5SDimitry Andric   void setStartStopPasses();
1210b57cec5SDimitry Andric 
1220b57cec5SDimitry Andric protected:
1230b57cec5SDimitry Andric   LLVMTargetMachine *TM;
1240b57cec5SDimitry Andric   PassConfigImpl *Impl = nullptr; // Internal data structures
1250b57cec5SDimitry Andric   bool Initialized = false; // Flagged after all passes are configured.
1260b57cec5SDimitry Andric 
1270b57cec5SDimitry Andric   // Target Pass Options
1280b57cec5SDimitry Andric   // Targets provide a default setting, user flags override.
1290b57cec5SDimitry Andric   bool DisableVerify = false;
1300b57cec5SDimitry Andric 
1310b57cec5SDimitry Andric   /// Default setting for -enable-tail-merge on this target.
1320b57cec5SDimitry Andric   bool EnableTailMerge = true;
1330b57cec5SDimitry Andric 
1345f757f3fSDimitry Andric   /// Enable sinking of instructions in MachineSink where a computation can be
1355f757f3fSDimitry Andric   /// folded into the addressing mode of a memory load/store instruction or
1365f757f3fSDimitry Andric   /// replace a copy.
1375f757f3fSDimitry Andric   bool EnableSinkAndFold = false;
1385f757f3fSDimitry Andric 
1390b57cec5SDimitry Andric   /// Require processing of functions such that callees are generated before
1400b57cec5SDimitry Andric   /// callers.
1410b57cec5SDimitry Andric   bool RequireCodeGenSCCOrder = false;
1420b57cec5SDimitry Andric 
1430b57cec5SDimitry Andric   /// Add the actual instruction selection passes. This does not include
1440b57cec5SDimitry Andric   /// preparation passes on IR.
1450b57cec5SDimitry Andric   bool addCoreISelPasses();
1460b57cec5SDimitry Andric 
1470b57cec5SDimitry Andric public:
1480b57cec5SDimitry Andric   TargetPassConfig(LLVMTargetMachine &TM, PassManagerBase &pm);
1490b57cec5SDimitry Andric   // Dummy constructor.
1500b57cec5SDimitry Andric   TargetPassConfig();
1510b57cec5SDimitry Andric 
1520b57cec5SDimitry Andric   ~TargetPassConfig() override;
1530b57cec5SDimitry Andric 
1540b57cec5SDimitry Andric   static char ID;
1550b57cec5SDimitry Andric 
1560b57cec5SDimitry Andric   /// Get the right type of TargetMachine for this target.
1570b57cec5SDimitry Andric   template<typename TMC> TMC &getTM() const {
1580b57cec5SDimitry Andric     return *static_cast<TMC*>(TM);
1590b57cec5SDimitry Andric   }
1600b57cec5SDimitry Andric 
1610b57cec5SDimitry Andric   //
1620b57cec5SDimitry Andric   void setInitialized() { Initialized = true; }
1630b57cec5SDimitry Andric 
1645f757f3fSDimitry Andric   CodeGenOptLevel getOptLevel() const;
1650b57cec5SDimitry Andric 
1660b57cec5SDimitry Andric   /// Returns true if one of the `-start-after`, `-start-before`, `-stop-after`
1670b57cec5SDimitry Andric   /// or `-stop-before` options is set.
1680b57cec5SDimitry Andric   static bool hasLimitedCodeGenPipeline();
1690b57cec5SDimitry Andric 
1700b57cec5SDimitry Andric   /// Returns true if none of the `-stop-before` and `-stop-after` options is
1710b57cec5SDimitry Andric   /// set.
1720b57cec5SDimitry Andric   static bool willCompleteCodeGenPipeline();
1730b57cec5SDimitry Andric 
174*7a6dacacSDimitry Andric   /// If hasLimitedCodeGenPipeline is true, this method returns
175*7a6dacacSDimitry Andric   /// a string with the name of the options that caused this
176*7a6dacacSDimitry Andric   /// pipeline to be limited.
177*7a6dacacSDimitry Andric   static std::string getLimitedCodeGenPipelineReason();
178*7a6dacacSDimitry Andric 
179*7a6dacacSDimitry Andric   struct StartStopInfo {
180*7a6dacacSDimitry Andric     bool StartAfter;
181*7a6dacacSDimitry Andric     bool StopAfter;
182*7a6dacacSDimitry Andric     unsigned StartInstanceNum;
183*7a6dacacSDimitry Andric     unsigned StopInstanceNum;
184*7a6dacacSDimitry Andric     StringRef StartPass;
185*7a6dacacSDimitry Andric     StringRef StopPass;
186*7a6dacacSDimitry Andric   };
187*7a6dacacSDimitry Andric 
188*7a6dacacSDimitry Andric   /// Returns pass name in `-stop-before` or `-stop-after`
189*7a6dacacSDimitry Andric   /// NOTE: New pass manager migration only
190*7a6dacacSDimitry Andric   static Expected<StartStopInfo>
191*7a6dacacSDimitry Andric   getStartStopInfo(PassInstrumentationCallbacks &PIC);
1920b57cec5SDimitry Andric 
1930b57cec5SDimitry Andric   void setDisableVerify(bool Disable) { setOpt(DisableVerify, Disable); }
1940b57cec5SDimitry Andric 
1950b57cec5SDimitry Andric   bool getEnableTailMerge() const { return EnableTailMerge; }
1960b57cec5SDimitry Andric   void setEnableTailMerge(bool Enable) { setOpt(EnableTailMerge, Enable); }
1970b57cec5SDimitry Andric 
1985f757f3fSDimitry Andric   bool getEnableSinkAndFold() const { return EnableSinkAndFold; }
1995f757f3fSDimitry Andric   void setEnableSinkAndFold(bool Enable) { setOpt(EnableSinkAndFold, Enable); }
2005f757f3fSDimitry Andric 
2010b57cec5SDimitry Andric   bool requiresCodeGenSCCOrder() const { return RequireCodeGenSCCOrder; }
2020b57cec5SDimitry Andric   void setRequiresCodeGenSCCOrder(bool Enable = true) {
2030b57cec5SDimitry Andric     setOpt(RequireCodeGenSCCOrder, Enable);
2040b57cec5SDimitry Andric   }
2050b57cec5SDimitry Andric 
2060b57cec5SDimitry Andric   /// Allow the target to override a specific pass without overriding the pass
2070b57cec5SDimitry Andric   /// pipeline. When passes are added to the standard pipeline at the
2080b57cec5SDimitry Andric   /// point where StandardID is expected, add TargetID in its place.
2090b57cec5SDimitry Andric   void substitutePass(AnalysisID StandardID, IdentifyingPassPtr TargetID);
2100b57cec5SDimitry Andric 
2110b57cec5SDimitry Andric   /// Insert InsertedPassID pass after TargetPassID pass.
212349cc55cSDimitry Andric   void insertPass(AnalysisID TargetPassID, IdentifyingPassPtr InsertedPassID);
2130b57cec5SDimitry Andric 
2140b57cec5SDimitry Andric   /// Allow the target to enable a specific standard pass by default.
2150b57cec5SDimitry Andric   void enablePass(AnalysisID PassID) { substitutePass(PassID, PassID); }
2160b57cec5SDimitry Andric 
2170b57cec5SDimitry Andric   /// Allow the target to disable a specific standard pass by default.
2180b57cec5SDimitry Andric   void disablePass(AnalysisID PassID) {
2190b57cec5SDimitry Andric     substitutePass(PassID, IdentifyingPassPtr());
2200b57cec5SDimitry Andric   }
2210b57cec5SDimitry Andric 
2220b57cec5SDimitry Andric   /// Return the pass substituted for StandardID by the target.
2230b57cec5SDimitry Andric   /// If no substitution exists, return StandardID.
2240b57cec5SDimitry Andric   IdentifyingPassPtr getPassSubstitution(AnalysisID StandardID) const;
2250b57cec5SDimitry Andric 
2260b57cec5SDimitry Andric   /// Return true if the pass has been substituted by the target or
2270b57cec5SDimitry Andric   /// overridden on the command line.
2280b57cec5SDimitry Andric   bool isPassSubstitutedOrOverridden(AnalysisID ID) const;
2290b57cec5SDimitry Andric 
2300b57cec5SDimitry Andric   /// Return true if the optimized regalloc pipeline is enabled.
2310b57cec5SDimitry Andric   bool getOptimizeRegAlloc() const;
2320b57cec5SDimitry Andric 
2330b57cec5SDimitry Andric   /// Return true if the default global register allocator is in use and
2340b57cec5SDimitry Andric   /// has not be overriden on the command line with '-regalloc=...'
2350b57cec5SDimitry Andric   bool usingDefaultRegAlloc() const;
2360b57cec5SDimitry Andric 
2370b57cec5SDimitry Andric   /// High level function that adds all passes necessary to go from llvm IR
2380b57cec5SDimitry Andric   /// representation to the MI representation.
2390b57cec5SDimitry Andric   /// Adds IR based lowering and target specific optimization passes and finally
2400b57cec5SDimitry Andric   /// the core instruction selection passes.
2410b57cec5SDimitry Andric   /// \returns true if an error occurred, false otherwise.
2420b57cec5SDimitry Andric   bool addISelPasses();
2430b57cec5SDimitry Andric 
2440b57cec5SDimitry Andric   /// Add common target configurable passes that perform LLVM IR to IR
2450b57cec5SDimitry Andric   /// transforms following machine independent optimization.
2460b57cec5SDimitry Andric   virtual void addIRPasses();
2470b57cec5SDimitry Andric 
2480b57cec5SDimitry Andric   /// Add passes to lower exception handling for the code generator.
2490b57cec5SDimitry Andric   void addPassesToHandleExceptions();
2500b57cec5SDimitry Andric 
2510b57cec5SDimitry Andric   /// Add pass to prepare the LLVM IR for code generation. This should be done
2520b57cec5SDimitry Andric   /// before exception handling preparation passes.
2530b57cec5SDimitry Andric   virtual void addCodeGenPrepare();
2540b57cec5SDimitry Andric 
2550b57cec5SDimitry Andric   /// Add common passes that perform LLVM IR to IR transforms in preparation for
2560b57cec5SDimitry Andric   /// instruction selection.
2570b57cec5SDimitry Andric   virtual void addISelPrepare();
2580b57cec5SDimitry Andric 
2590b57cec5SDimitry Andric   /// addInstSelector - This method should install an instruction selector pass,
2600b57cec5SDimitry Andric   /// which converts from LLVM code to machine instructions.
2610b57cec5SDimitry Andric   virtual bool addInstSelector() {
2620b57cec5SDimitry Andric     return true;
2630b57cec5SDimitry Andric   }
2640b57cec5SDimitry Andric 
2650b57cec5SDimitry Andric   /// This method should install an IR translator pass, which converts from
2660b57cec5SDimitry Andric   /// LLVM code to machine instructions with possibly generic opcodes.
2670b57cec5SDimitry Andric   virtual bool addIRTranslator() { return true; }
2680b57cec5SDimitry Andric 
2690b57cec5SDimitry Andric   /// This method may be implemented by targets that want to run passes
2700b57cec5SDimitry Andric   /// immediately before legalization.
2710b57cec5SDimitry Andric   virtual void addPreLegalizeMachineIR() {}
2720b57cec5SDimitry Andric 
2730b57cec5SDimitry Andric   /// This method should install a legalize pass, which converts the instruction
2740b57cec5SDimitry Andric   /// sequence into one that can be selected by the target.
2750b57cec5SDimitry Andric   virtual bool addLegalizeMachineIR() { return true; }
2760b57cec5SDimitry Andric 
2770b57cec5SDimitry Andric   /// This method may be implemented by targets that want to run passes
2780b57cec5SDimitry Andric   /// immediately before the register bank selection.
2790b57cec5SDimitry Andric   virtual void addPreRegBankSelect() {}
2800b57cec5SDimitry Andric 
2810b57cec5SDimitry Andric   /// This method should install a register bank selector pass, which
2820b57cec5SDimitry Andric   /// assigns register banks to virtual registers without a register
2830b57cec5SDimitry Andric   /// class or register banks.
2840b57cec5SDimitry Andric   virtual bool addRegBankSelect() { return true; }
2850b57cec5SDimitry Andric 
2860b57cec5SDimitry Andric   /// This method may be implemented by targets that want to run passes
2870b57cec5SDimitry Andric   /// immediately before the (global) instruction selection.
2880b57cec5SDimitry Andric   virtual void addPreGlobalInstructionSelect() {}
2890b57cec5SDimitry Andric 
2900b57cec5SDimitry Andric   /// This method should install a (global) instruction selector pass, which
2910b57cec5SDimitry Andric   /// converts possibly generic instructions to fully target-specific
2920b57cec5SDimitry Andric   /// instructions, thereby constraining all generic virtual registers to
2930b57cec5SDimitry Andric   /// register classes.
2940b57cec5SDimitry Andric   virtual bool addGlobalInstructionSelect() { return true; }
2950b57cec5SDimitry Andric 
2960b57cec5SDimitry Andric   /// Add the complete, standard set of LLVM CodeGen passes.
2970b57cec5SDimitry Andric   /// Fully developed targets will not generally override this.
2980b57cec5SDimitry Andric   virtual void addMachinePasses();
2990b57cec5SDimitry Andric 
3000b57cec5SDimitry Andric   /// Create an instance of ScheduleDAGInstrs to be run within the standard
3010b57cec5SDimitry Andric   /// MachineScheduler pass for this function and target at the current
3020b57cec5SDimitry Andric   /// optimization level.
3030b57cec5SDimitry Andric   ///
3040b57cec5SDimitry Andric   /// This can also be used to plug a new MachineSchedStrategy into an instance
3050b57cec5SDimitry Andric   /// of the standard ScheduleDAGMI:
3068bcb0991SDimitry Andric   ///   return new ScheduleDAGMI(C, std::make_unique<MyStrategy>(C), /*RemoveKillFlags=*/false)
3070b57cec5SDimitry Andric   ///
3080b57cec5SDimitry Andric   /// Return NULL to select the default (generic) machine scheduler.
3090b57cec5SDimitry Andric   virtual ScheduleDAGInstrs *
3100b57cec5SDimitry Andric   createMachineScheduler(MachineSchedContext *C) const {
3110b57cec5SDimitry Andric     return nullptr;
3120b57cec5SDimitry Andric   }
3130b57cec5SDimitry Andric 
3140b57cec5SDimitry Andric   /// Similar to createMachineScheduler but used when postRA machine scheduling
3150b57cec5SDimitry Andric   /// is enabled.
3160b57cec5SDimitry Andric   virtual ScheduleDAGInstrs *
3170b57cec5SDimitry Andric   createPostMachineScheduler(MachineSchedContext *C) const {
3180b57cec5SDimitry Andric     return nullptr;
3190b57cec5SDimitry Andric   }
3200b57cec5SDimitry Andric 
3210b57cec5SDimitry Andric   /// printAndVerify - Add a pass to dump then verify the machine function, if
3220b57cec5SDimitry Andric   /// those steps are enabled.
3230b57cec5SDimitry Andric   void printAndVerify(const std::string &Banner);
3240b57cec5SDimitry Andric 
3250b57cec5SDimitry Andric   /// Add a pass to print the machine function if printing is enabled.
3260b57cec5SDimitry Andric   void addPrintPass(const std::string &Banner);
3270b57cec5SDimitry Andric 
3280b57cec5SDimitry Andric   /// Add a pass to perform basic verification of the machine function if
3290b57cec5SDimitry Andric   /// verification is enabled.
3300b57cec5SDimitry Andric   void addVerifyPass(const std::string &Banner);
3310b57cec5SDimitry Andric 
3325ffd83dbSDimitry Andric   /// Add a pass to add synthesized debug info to the MIR.
3335ffd83dbSDimitry Andric   void addDebugifyPass();
3345ffd83dbSDimitry Andric 
3355ffd83dbSDimitry Andric   /// Add a pass to remove debug info from the MIR.
3365ffd83dbSDimitry Andric   void addStripDebugPass();
3375ffd83dbSDimitry Andric 
338e8d8bef9SDimitry Andric   /// Add a pass to check synthesized debug info for MIR.
339e8d8bef9SDimitry Andric   void addCheckDebugPass();
340e8d8bef9SDimitry Andric 
3415ffd83dbSDimitry Andric   /// Add standard passes before a pass that's about to be added. For example,
3425ffd83dbSDimitry Andric   /// the DebugifyMachineModulePass if it is enabled.
3435ffd83dbSDimitry Andric   void addMachinePrePasses(bool AllowDebugify = true);
3445ffd83dbSDimitry Andric 
3455ffd83dbSDimitry Andric   /// Add standard passes after a pass that has just been added. For example,
3465ffd83dbSDimitry Andric   /// the MachineVerifier if it is enabled.
347349cc55cSDimitry Andric   void addMachinePostPasses(const std::string &Banner);
3485ffd83dbSDimitry Andric 
3490b57cec5SDimitry Andric   /// Check whether or not GlobalISel should abort on error.
3500b57cec5SDimitry Andric   /// When this is disabled, GlobalISel will fall back on SDISel instead of
3510b57cec5SDimitry Andric   /// erroring out.
3520b57cec5SDimitry Andric   bool isGlobalISelAbortEnabled() const;
3530b57cec5SDimitry Andric 
3540b57cec5SDimitry Andric   /// Check whether or not a diagnostic should be emitted when GlobalISel
3550b57cec5SDimitry Andric   /// uses the fallback path. In other words, it will emit a diagnostic
3560b57cec5SDimitry Andric   /// when GlobalISel failed and isGlobalISelAbortEnabled is false.
3570b57cec5SDimitry Andric   virtual bool reportDiagnosticWhenGlobalISelFallback() const;
3580b57cec5SDimitry Andric 
3590b57cec5SDimitry Andric   /// Check whether continuous CSE should be enabled in GISel passes.
3600b57cec5SDimitry Andric   /// By default, it's enabled for non O0 levels.
3610b57cec5SDimitry Andric   virtual bool isGISelCSEEnabled() const;
3620b57cec5SDimitry Andric 
3630b57cec5SDimitry Andric   /// Returns the CSEConfig object to use for the current optimization level.
3640b57cec5SDimitry Andric   virtual std::unique_ptr<CSEConfigBase> getCSEConfig() const;
3650b57cec5SDimitry Andric 
3660b57cec5SDimitry Andric protected:
3670b57cec5SDimitry Andric   // Helper to verify the analysis is really immutable.
3680b57cec5SDimitry Andric   void setOpt(bool &Opt, bool Val);
3690b57cec5SDimitry Andric 
37081ad6265SDimitry Andric   /// Return true if register allocator is specified by -regalloc=override.
37181ad6265SDimitry Andric   bool isCustomizedRegAlloc();
37281ad6265SDimitry Andric 
3730b57cec5SDimitry Andric   /// Methods with trivial inline returns are convenient points in the common
3740b57cec5SDimitry Andric   /// codegen pass pipeline where targets may insert passes. Methods with
3750b57cec5SDimitry Andric   /// out-of-line standard implementations are major CodeGen stages called by
3760b57cec5SDimitry Andric   /// addMachinePasses. Some targets may override major stages when inserting
3770b57cec5SDimitry Andric   /// passes is insufficient, but maintaining overriden stages is more work.
3780b57cec5SDimitry Andric   ///
3790b57cec5SDimitry Andric 
3800b57cec5SDimitry Andric   /// addPreISelPasses - This method should add any "last minute" LLVM->LLVM
3810b57cec5SDimitry Andric   /// passes (which are run just before instruction selector).
3820b57cec5SDimitry Andric   virtual bool addPreISel() {
3830b57cec5SDimitry Andric     return true;
3840b57cec5SDimitry Andric   }
3850b57cec5SDimitry Andric 
3860b57cec5SDimitry Andric   /// addMachineSSAOptimization - Add standard passes that optimize machine
3870b57cec5SDimitry Andric   /// instructions in SSA form.
3880b57cec5SDimitry Andric   virtual void addMachineSSAOptimization();
3890b57cec5SDimitry Andric 
3900b57cec5SDimitry Andric   /// Add passes that optimize instruction level parallelism for out-of-order
3910b57cec5SDimitry Andric   /// targets. These passes are run while the machine code is still in SSA
3920b57cec5SDimitry Andric   /// form, so they can use MachineTraceMetrics to control their heuristics.
3930b57cec5SDimitry Andric   ///
3940b57cec5SDimitry Andric   /// All passes added here should preserve the MachineDominatorTree,
3950b57cec5SDimitry Andric   /// MachineLoopInfo, and MachineTraceMetrics analyses.
3960b57cec5SDimitry Andric   virtual bool addILPOpts() {
3970b57cec5SDimitry Andric     return false;
3980b57cec5SDimitry Andric   }
3990b57cec5SDimitry Andric 
4000b57cec5SDimitry Andric   /// This method may be implemented by targets that want to run passes
4010b57cec5SDimitry Andric   /// immediately before register allocation.
4020b57cec5SDimitry Andric   virtual void addPreRegAlloc() { }
4030b57cec5SDimitry Andric 
4040b57cec5SDimitry Andric   /// createTargetRegisterAllocator - Create the register allocator pass for
4050b57cec5SDimitry Andric   /// this target at the current optimization level.
4060b57cec5SDimitry Andric   virtual FunctionPass *createTargetRegisterAllocator(bool Optimized);
4070b57cec5SDimitry Andric 
4080b57cec5SDimitry Andric   /// addFastRegAlloc - Add the minimum set of target-independent passes that
4090b57cec5SDimitry Andric   /// are required for fast register allocation.
4100b57cec5SDimitry Andric   virtual void addFastRegAlloc();
4110b57cec5SDimitry Andric 
4120b57cec5SDimitry Andric   /// addOptimizedRegAlloc - Add passes related to register allocation.
4130b57cec5SDimitry Andric   /// LLVMTargetMachine provides standard regalloc passes for most targets.
4140b57cec5SDimitry Andric   virtual void addOptimizedRegAlloc();
4150b57cec5SDimitry Andric 
4160b57cec5SDimitry Andric   /// addPreRewrite - Add passes to the optimized register allocation pipeline
4170b57cec5SDimitry Andric   /// after register allocation is complete, but before virtual registers are
4180b57cec5SDimitry Andric   /// rewritten to physical registers.
4190b57cec5SDimitry Andric   ///
4200b57cec5SDimitry Andric   /// These passes must preserve VirtRegMap and LiveIntervals, and when running
4210b57cec5SDimitry Andric   /// after RABasic or RAGreedy, they should take advantage of LiveRegMatrix.
4220b57cec5SDimitry Andric   /// When these passes run, VirtRegMap contains legal physreg assignments for
4230b57cec5SDimitry Andric   /// all virtual registers.
4240b57cec5SDimitry Andric   ///
4250b57cec5SDimitry Andric   /// Note if the target overloads addRegAssignAndRewriteOptimized, this may not
4265f757f3fSDimitry Andric   /// be honored. This is also not generally used for the fast variant,
4270b57cec5SDimitry Andric   /// where the allocation and rewriting are done in one pass.
4280b57cec5SDimitry Andric   virtual bool addPreRewrite() {
4290b57cec5SDimitry Andric     return false;
4300b57cec5SDimitry Andric   }
4310b57cec5SDimitry Andric 
432fe6060f1SDimitry Andric   /// addPostFastRegAllocRewrite - Add passes to the optimized register
433fe6060f1SDimitry Andric   /// allocation pipeline after fast register allocation is complete.
434fe6060f1SDimitry Andric   virtual bool addPostFastRegAllocRewrite() { return false; }
435fe6060f1SDimitry Andric 
4360b57cec5SDimitry Andric   /// Add passes to be run immediately after virtual registers are rewritten
4370b57cec5SDimitry Andric   /// to physical registers.
4380b57cec5SDimitry Andric   virtual void addPostRewrite() { }
4390b57cec5SDimitry Andric 
4400b57cec5SDimitry Andric   /// This method may be implemented by targets that want to run passes after
4410b57cec5SDimitry Andric   /// register allocation pass pipeline but before prolog-epilog insertion.
4420b57cec5SDimitry Andric   virtual void addPostRegAlloc() { }
4430b57cec5SDimitry Andric 
4440b57cec5SDimitry Andric   /// Add passes that optimize machine instructions after register allocation.
4450b57cec5SDimitry Andric   virtual void addMachineLateOptimization();
4460b57cec5SDimitry Andric 
4470b57cec5SDimitry Andric   /// This method may be implemented by targets that want to run passes after
4480b57cec5SDimitry Andric   /// prolog-epilog insertion and before the second instruction scheduling pass.
4490b57cec5SDimitry Andric   virtual void addPreSched2() { }
4500b57cec5SDimitry Andric 
4510b57cec5SDimitry Andric   /// addGCPasses - Add late codegen passes that analyze code for garbage
4520b57cec5SDimitry Andric   /// collection. This should return true if GC info should be printed after
4530b57cec5SDimitry Andric   /// these passes.
4540b57cec5SDimitry Andric   virtual bool addGCPasses();
4550b57cec5SDimitry Andric 
4560b57cec5SDimitry Andric   /// Add standard basic block placement passes.
4570b57cec5SDimitry Andric   virtual void addBlockPlacement();
4580b57cec5SDimitry Andric 
4590b57cec5SDimitry Andric   /// This pass may be implemented by targets that want to run passes
4600b57cec5SDimitry Andric   /// immediately before machine code is emitted.
4610b57cec5SDimitry Andric   virtual void addPreEmitPass() { }
4620b57cec5SDimitry Andric 
46306c3fb27SDimitry Andric   /// This pass may be implemented by targets that want to run passes
46406c3fb27SDimitry Andric   /// immediately after basic block sections are assigned.
46506c3fb27SDimitry Andric   virtual void addPostBBSections() {}
46606c3fb27SDimitry Andric 
4670b57cec5SDimitry Andric   /// Targets may add passes immediately before machine code is emitted in this
4680b57cec5SDimitry Andric   /// callback. This is called even later than `addPreEmitPass`.
4690b57cec5SDimitry Andric   // FIXME: Rename `addPreEmitPass` to something more sensible given its actual
4700b57cec5SDimitry Andric   // position and remove the `2` suffix here as this callback is what
4710b57cec5SDimitry Andric   // `addPreEmitPass` *should* be but in reality isn't.
4720b57cec5SDimitry Andric   virtual void addPreEmitPass2() {}
4730b57cec5SDimitry Andric 
4740b57cec5SDimitry Andric   /// Utilities for targets to add passes to the pass manager.
4750b57cec5SDimitry Andric   ///
4760b57cec5SDimitry Andric 
4770b57cec5SDimitry Andric   /// Add a CodeGen pass at this point in the pipeline after checking overrides.
4780b57cec5SDimitry Andric   /// Return the pass that was added, or zero if no pass was added.
479349cc55cSDimitry Andric   AnalysisID addPass(AnalysisID PassID);
4800b57cec5SDimitry Andric 
4810b57cec5SDimitry Andric   /// Add a pass to the PassManager if that pass is supposed to be run, as
4820b57cec5SDimitry Andric   /// determined by the StartAfter and StopAfter options. Takes ownership of the
4830b57cec5SDimitry Andric   /// pass.
484349cc55cSDimitry Andric   void addPass(Pass *P);
4850b57cec5SDimitry Andric 
4860b57cec5SDimitry Andric   /// addMachinePasses helper to create the target-selected or overriden
4870b57cec5SDimitry Andric   /// regalloc pass.
4880b57cec5SDimitry Andric   virtual FunctionPass *createRegAllocPass(bool Optimized);
4890b57cec5SDimitry Andric 
490e8d8bef9SDimitry Andric   /// Add core register allocator passes which do the actual register assignment
4910b57cec5SDimitry Andric   /// and rewriting. \returns true if any passes were added.
492e8d8bef9SDimitry Andric   virtual bool addRegAssignAndRewriteFast();
493e8d8bef9SDimitry Andric   virtual bool addRegAssignAndRewriteOptimized();
4940b57cec5SDimitry Andric };
4950b57cec5SDimitry Andric 
496e8d8bef9SDimitry Andric void registerCodeGenCallback(PassInstrumentationCallbacks &PIC,
497e8d8bef9SDimitry Andric                              LLVMTargetMachine &);
498e8d8bef9SDimitry Andric 
4990b57cec5SDimitry Andric } // end namespace llvm
5000b57cec5SDimitry Andric 
5010b57cec5SDimitry Andric #endif // LLVM_CODEGEN_TARGETPASSCONFIG_H
502