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