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