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