1 //===- llvm/CodeGen/TargetSubtargetInfo.h - Target Information --*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file describes the subtarget options of a Target machine. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #ifndef LLVM_CODEGEN_TARGETSUBTARGETINFO_H 14 #define LLVM_CODEGEN_TARGETSUBTARGETINFO_H 15 16 #include "llvm/ADT/APInt.h" 17 #include "llvm/ADT/ArrayRef.h" 18 #include "llvm/ADT/SmallVector.h" 19 #include "llvm/ADT/StringRef.h" 20 #include "llvm/CodeGen/PBQPRAConstraint.h" 21 #include "llvm/CodeGen/ScheduleDAGMutation.h" 22 #include "llvm/CodeGen/SchedulerRegistry.h" 23 #include "llvm/MC/MCSubtargetInfo.h" 24 #include "llvm/Support/CodeGen.h" 25 #include <memory> 26 #include <vector> 27 28 namespace llvm { 29 30 class CallLowering; 31 class InlineAsmLowering; 32 class InstrItineraryData; 33 struct InstrStage; 34 class InstructionSelector; 35 class LegalizerInfo; 36 class MachineInstr; 37 struct MachineSchedPolicy; 38 struct MCReadAdvanceEntry; 39 struct MCWriteLatencyEntry; 40 struct MCWriteProcResEntry; 41 class RegisterBankInfo; 42 class SDep; 43 class SelectionDAGTargetInfo; 44 class SUnit; 45 class TargetFrameLowering; 46 class TargetInstrInfo; 47 class TargetLowering; 48 class TargetRegisterClass; 49 class TargetRegisterInfo; 50 class TargetSchedModel; 51 class Triple; 52 53 //===----------------------------------------------------------------------===// 54 /// 55 /// TargetSubtargetInfo - Generic base class for all target subtargets. All 56 /// Target-specific options that control code generation and printing should 57 /// be exposed through a TargetSubtargetInfo-derived class. 58 /// 59 class TargetSubtargetInfo : public MCSubtargetInfo { 60 protected: // Can only create subclasses... 61 TargetSubtargetInfo(const Triple &TT, StringRef CPU, StringRef TuneCPU, 62 StringRef FS, ArrayRef<SubtargetFeatureKV> PF, 63 ArrayRef<SubtargetSubTypeKV> PD, 64 const MCWriteProcResEntry *WPR, 65 const MCWriteLatencyEntry *WL, 66 const MCReadAdvanceEntry *RA, const InstrStage *IS, 67 const unsigned *OC, const unsigned *FP); 68 69 public: 70 // AntiDepBreakMode - Type of anti-dependence breaking that should 71 // be performed before post-RA scheduling. 72 using AntiDepBreakMode = enum { ANTIDEP_NONE, ANTIDEP_CRITICAL, ANTIDEP_ALL }; 73 using RegClassVector = SmallVectorImpl<const TargetRegisterClass *>; 74 75 TargetSubtargetInfo() = delete; 76 TargetSubtargetInfo(const TargetSubtargetInfo &) = delete; 77 TargetSubtargetInfo &operator=(const TargetSubtargetInfo &) = delete; 78 ~TargetSubtargetInfo() override; 79 isXRaySupported()80 virtual bool isXRaySupported() const { return false; } 81 82 // Interfaces to the major aspects of target machine information: 83 // 84 // -- Instruction opcode and operand information 85 // -- Pipelines and scheduling information 86 // -- Stack frame information 87 // -- Selection DAG lowering information 88 // -- Call lowering information 89 // 90 // N.B. These objects may change during compilation. It's not safe to cache 91 // them between functions. getInstrInfo()92 virtual const TargetInstrInfo *getInstrInfo() const { return nullptr; } getFrameLowering()93 virtual const TargetFrameLowering *getFrameLowering() const { 94 return nullptr; 95 } getTargetLowering()96 virtual const TargetLowering *getTargetLowering() const { return nullptr; } getSelectionDAGInfo()97 virtual const SelectionDAGTargetInfo *getSelectionDAGInfo() const { 98 return nullptr; 99 } getCallLowering()100 virtual const CallLowering *getCallLowering() const { return nullptr; } 101 getInlineAsmLowering()102 virtual const InlineAsmLowering *getInlineAsmLowering() const { 103 return nullptr; 104 } 105 106 // FIXME: This lets targets specialize the selector by subtarget (which lets 107 // us do things like a dedicated avx512 selector). However, we might want 108 // to also specialize selectors by MachineFunction, which would let us be 109 // aware of optsize/optnone and such. getInstructionSelector()110 virtual InstructionSelector *getInstructionSelector() const { 111 return nullptr; 112 } 113 114 /// Target can subclass this hook to select a different DAG scheduler. 115 virtual RegisterScheduler::FunctionPassCtor getDAGScheduler(CodeGenOpt::Level)116 getDAGScheduler(CodeGenOpt::Level) const { 117 return nullptr; 118 } 119 getLegalizerInfo()120 virtual const LegalizerInfo *getLegalizerInfo() const { return nullptr; } 121 122 /// getRegisterInfo - If register information is available, return it. If 123 /// not, return null. getRegisterInfo()124 virtual const TargetRegisterInfo *getRegisterInfo() const { return nullptr; } 125 126 /// If the information for the register banks is available, return it. 127 /// Otherwise return nullptr. getRegBankInfo()128 virtual const RegisterBankInfo *getRegBankInfo() const { return nullptr; } 129 130 /// getInstrItineraryData - Returns instruction itinerary data for the target 131 /// or specific subtarget. getInstrItineraryData()132 virtual const InstrItineraryData *getInstrItineraryData() const { 133 return nullptr; 134 } 135 136 /// Resolve a SchedClass at runtime, where SchedClass identifies an 137 /// MCSchedClassDesc with the isVariant property. This may return the ID of 138 /// another variant SchedClass, but repeated invocation must quickly terminate 139 /// in a nonvariant SchedClass. resolveSchedClass(unsigned SchedClass,const MachineInstr * MI,const TargetSchedModel * SchedModel)140 virtual unsigned resolveSchedClass(unsigned SchedClass, 141 const MachineInstr *MI, 142 const TargetSchedModel *SchedModel) const { 143 return 0; 144 } 145 146 /// Returns true if MI is a dependency breaking zero-idiom instruction for the 147 /// subtarget. 148 /// 149 /// This function also sets bits in Mask related to input operands that 150 /// are not in a data dependency relationship. There is one bit for each 151 /// machine operand; implicit operands follow explicit operands in the bit 152 /// representation used for Mask. An empty (i.e. a mask with all bits 153 /// cleared) means: data dependencies are "broken" for all the explicit input 154 /// machine operands of MI. isZeroIdiom(const MachineInstr * MI,APInt & Mask)155 virtual bool isZeroIdiom(const MachineInstr *MI, APInt &Mask) const { 156 return false; 157 } 158 159 /// Returns true if MI is a dependency breaking instruction for the subtarget. 160 /// 161 /// Similar in behavior to `isZeroIdiom`. However, it knows how to identify 162 /// all dependency breaking instructions (i.e. not just zero-idioms). 163 /// 164 /// As for `isZeroIdiom`, this method returns a mask of "broken" dependencies. 165 /// (See method `isZeroIdiom` for a detailed description of Mask). isDependencyBreaking(const MachineInstr * MI,APInt & Mask)166 virtual bool isDependencyBreaking(const MachineInstr *MI, APInt &Mask) const { 167 return isZeroIdiom(MI, Mask); 168 } 169 170 /// Returns true if MI is a candidate for move elimination. 171 /// 172 /// A candidate for move elimination may be optimized out at register renaming 173 /// stage. Subtargets can specify the set of optimizable moves by 174 /// instantiating tablegen class `IsOptimizableRegisterMove` (see 175 /// llvm/Target/TargetInstrPredicate.td). 176 /// 177 /// SubtargetEmitter is responsible for processing all the definitions of class 178 /// IsOptimizableRegisterMove, and auto-generate an override for this method. isOptimizableRegisterMove(const MachineInstr * MI)179 virtual bool isOptimizableRegisterMove(const MachineInstr *MI) const { 180 return false; 181 } 182 183 /// True if the subtarget should run MachineScheduler after aggressive 184 /// coalescing. 185 /// 186 /// This currently replaces the SelectionDAG scheduler with the "source" order 187 /// scheduler (though see below for an option to turn this off and use the 188 /// TargetLowering preference). It does not yet disable the postRA scheduler. 189 virtual bool enableMachineScheduler() const; 190 191 /// True if the machine scheduler should disable the TLI preference 192 /// for preRA scheduling with the source level scheduler. enableMachineSchedDefaultSched()193 virtual bool enableMachineSchedDefaultSched() const { return true; } 194 195 /// True if the subtarget should run MachinePipeliner enableMachinePipeliner()196 virtual bool enableMachinePipeliner() const { return true; }; 197 198 /// True if the subtarget should enable joining global copies. 199 /// 200 /// By default this is enabled if the machine scheduler is enabled, but 201 /// can be overridden. 202 virtual bool enableJoinGlobalCopies() const; 203 204 /// True if the subtarget should run a scheduler after register allocation. 205 /// 206 /// By default this queries the PostRAScheduling bit in the scheduling model 207 /// which is the preferred way to influence this. 208 virtual bool enablePostRAScheduler() const; 209 210 /// True if the subtarget should run a machine scheduler after register 211 /// allocation. 212 virtual bool enablePostRAMachineScheduler() const; 213 214 /// True if the subtarget should run the atomic expansion pass. 215 virtual bool enableAtomicExpand() const; 216 217 /// True if the subtarget should run the indirectbr expansion pass. 218 virtual bool enableIndirectBrExpand() const; 219 220 /// Override generic scheduling policy within a region. 221 /// 222 /// This is a convenient way for targets that don't provide any custom 223 /// scheduling heuristics (no custom MachineSchedStrategy) to make 224 /// changes to the generic scheduling policy. overrideSchedPolicy(MachineSchedPolicy & Policy,unsigned NumRegionInstrs)225 virtual void overrideSchedPolicy(MachineSchedPolicy &Policy, 226 unsigned NumRegionInstrs) const {} 227 228 // Perform target-specific adjustments to the latency of a schedule 229 // dependency. 230 // If a pair of operands is associated with the schedule dependency, DefOpIdx 231 // and UseOpIdx are the indices of the operands in Def and Use, respectively. 232 // Otherwise, either may be -1. adjustSchedDependency(SUnit * Def,int DefOpIdx,SUnit * Use,int UseOpIdx,SDep & Dep)233 virtual void adjustSchedDependency(SUnit *Def, int DefOpIdx, SUnit *Use, 234 int UseOpIdx, SDep &Dep) const {} 235 236 // For use with PostRAScheduling: get the anti-dependence breaking that should 237 // be performed before post-RA scheduling. getAntiDepBreakMode()238 virtual AntiDepBreakMode getAntiDepBreakMode() const { return ANTIDEP_NONE; } 239 240 // For use with PostRAScheduling: in CriticalPathRCs, return any register 241 // classes that should only be considered for anti-dependence breaking if they 242 // are on the critical path. getCriticalPathRCs(RegClassVector & CriticalPathRCs)243 virtual void getCriticalPathRCs(RegClassVector &CriticalPathRCs) const { 244 return CriticalPathRCs.clear(); 245 } 246 247 // Provide an ordered list of schedule DAG mutations for the post-RA 248 // scheduler. getPostRAMutations(std::vector<std::unique_ptr<ScheduleDAGMutation>> & Mutations)249 virtual void getPostRAMutations( 250 std::vector<std::unique_ptr<ScheduleDAGMutation>> &Mutations) const { 251 } 252 253 // Provide an ordered list of schedule DAG mutations for the machine 254 // pipeliner. getSMSMutations(std::vector<std::unique_ptr<ScheduleDAGMutation>> & Mutations)255 virtual void getSMSMutations( 256 std::vector<std::unique_ptr<ScheduleDAGMutation>> &Mutations) const { 257 } 258 259 /// Default to DFA for resource management, return false when target will use 260 /// ProcResource in InstrSchedModel instead. useDFAforSMS()261 virtual bool useDFAforSMS() const { return true; } 262 263 // For use with PostRAScheduling: get the minimum optimization level needed 264 // to enable post-RA scheduling. getOptLevelToEnablePostRAScheduler()265 virtual CodeGenOpt::Level getOptLevelToEnablePostRAScheduler() const { 266 return CodeGenOpt::Default; 267 } 268 269 /// True if the subtarget should run the local reassignment 270 /// heuristic of the register allocator. 271 /// This heuristic may be compile time intensive, \p OptLevel provides 272 /// a finer grain to tune the register allocator. 273 virtual bool enableRALocalReassignment(CodeGenOpt::Level OptLevel) const; 274 275 /// True if the subtarget should consider the cost of local intervals 276 /// created by a split candidate when choosing the best split candidate. This 277 /// heuristic may be compile time intensive. 278 virtual bool enableAdvancedRASplitCost() const; 279 280 /// Enable use of alias analysis during code generation (during MI 281 /// scheduling, DAGCombine, etc.). 282 virtual bool useAA() const; 283 284 /// \brief Sink addresses into blocks using GEP instructions rather than 285 /// pointer casts and arithmetic. addrSinkUsingGEPs()286 virtual bool addrSinkUsingGEPs() const { 287 return useAA(); 288 } 289 290 /// Enable the use of the early if conversion pass. enableEarlyIfConversion()291 virtual bool enableEarlyIfConversion() const { return false; } 292 293 /// Return PBQPConstraint(s) for the target. 294 /// 295 /// Override to provide custom PBQP constraints. getCustomPBQPConstraints()296 virtual std::unique_ptr<PBQPRAConstraint> getCustomPBQPConstraints() const { 297 return nullptr; 298 } 299 300 /// Enable tracking of subregister liveness in register allocator. 301 /// Please use MachineRegisterInfo::subRegLivenessEnabled() instead where 302 /// possible. enableSubRegLiveness()303 virtual bool enableSubRegLiveness() const { return false; } 304 305 /// This is called after a .mir file was loaded. 306 virtual void mirFileLoaded(MachineFunction &MF) const; 307 308 /// True if the register allocator should use the allocation orders exactly as 309 /// written in the tablegen descriptions, false if it should allocate 310 /// the specified physical register later if is it callee-saved. ignoreCSRForAllocationOrder(const MachineFunction & MF,unsigned PhysReg)311 virtual bool ignoreCSRForAllocationOrder(const MachineFunction &MF, 312 unsigned PhysReg) const { 313 return false; 314 } 315 }; 316 317 } // end namespace llvm 318 319 #endif // LLVM_CODEGEN_TARGETSUBTARGETINFO_H 320