1 //===- llvm/CodeGen/TargetSubtargetInfo.h - Target Information --*- C++ -*-===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file describes the subtarget options of a Target machine. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CODEGEN_TARGETSUBTARGETINFO_H 15 #define LLVM_CODEGEN_TARGETSUBTARGETINFO_H 16 17 #include "llvm/ADT/APInt.h" 18 #include "llvm/ADT/ArrayRef.h" 19 #include "llvm/ADT/SmallVector.h" 20 #include "llvm/ADT/StringRef.h" 21 #include "llvm/CodeGen/PBQPRAConstraint.h" 22 #include "llvm/CodeGen/ScheduleDAGMutation.h" 23 #include "llvm/CodeGen/SchedulerRegistry.h" 24 #include "llvm/MC/MCSubtargetInfo.h" 25 #include "llvm/Support/CodeGen.h" 26 #include <memory> 27 #include <vector> 28 29 30 namespace llvm { 31 32 class CallLowering; 33 class InstrItineraryData; 34 struct InstrStage; 35 class InstructionSelector; 36 class LegalizerInfo; 37 class MachineInstr; 38 struct MachineSchedPolicy; 39 struct MCReadAdvanceEntry; 40 struct MCWriteLatencyEntry; 41 struct MCWriteProcResEntry; 42 class RegisterBankInfo; 43 class SDep; 44 class SelectionDAGTargetInfo; 45 struct SubtargetFeatureKV; 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<SubtargetFeatureKV> PD, 67 const SubtargetInfoKV *ProcSched, 68 const MCWriteProcResEntry *WPR, 69 const MCWriteLatencyEntry *WL, 70 const MCReadAdvanceEntry *RA, const InstrStage *IS, 71 const unsigned *OC, const unsigned *FP); 72 73 public: 74 // AntiDepBreakMode - Type of anti-dependence breaking that should 75 // be performed before post-RA scheduling. 76 using AntiDepBreakMode = enum { ANTIDEP_NONE, ANTIDEP_CRITICAL, ANTIDEP_ALL }; 77 using RegClassVector = SmallVectorImpl<const TargetRegisterClass *>; 78 79 TargetSubtargetInfo() = delete; 80 TargetSubtargetInfo(const TargetSubtargetInfo &) = delete; 81 TargetSubtargetInfo &operator=(const TargetSubtargetInfo &) = delete; 82 ~TargetSubtargetInfo() override; 83 isXRaySupported()84 virtual bool isXRaySupported() const { return false; } 85 86 // Interfaces to the major aspects of target machine information: 87 // 88 // -- Instruction opcode and operand information 89 // -- Pipelines and scheduling information 90 // -- Stack frame information 91 // -- Selection DAG lowering information 92 // -- Call lowering information 93 // 94 // N.B. These objects may change during compilation. It's not safe to cache 95 // them between functions. getInstrInfo()96 virtual const TargetInstrInfo *getInstrInfo() const { return nullptr; } getFrameLowering()97 virtual const TargetFrameLowering *getFrameLowering() const { 98 return nullptr; 99 } getTargetLowering()100 virtual const TargetLowering *getTargetLowering() const { return nullptr; } getSelectionDAGInfo()101 virtual const SelectionDAGTargetInfo *getSelectionDAGInfo() const { 102 return nullptr; 103 } getCallLowering()104 virtual const CallLowering *getCallLowering() const { return nullptr; } 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 const InstructionSelector *getInstructionSelector() const { 111 return nullptr; 112 } 113 getHwMode()114 virtual unsigned getHwMode() const { return 0; } 115 116 /// Target can subclass this hook to select a different DAG scheduler. 117 virtual RegisterScheduler::FunctionPassCtor getDAGScheduler(CodeGenOpt::Level)118 getDAGScheduler(CodeGenOpt::Level) const { 119 return nullptr; 120 } 121 getLegalizerInfo()122 virtual const LegalizerInfo *getLegalizerInfo() const { return nullptr; } 123 124 /// getRegisterInfo - If register information is available, return it. If 125 /// not, return null. getRegisterInfo()126 virtual const TargetRegisterInfo *getRegisterInfo() const { return nullptr; } 127 128 /// If the information for the register banks is available, return it. 129 /// Otherwise return nullptr. getRegBankInfo()130 virtual const RegisterBankInfo *getRegBankInfo() const { return nullptr; } 131 132 /// getInstrItineraryData - Returns instruction itinerary data for the target 133 /// or specific subtarget. getInstrItineraryData()134 virtual const InstrItineraryData *getInstrItineraryData() const { 135 return nullptr; 136 } 137 138 /// Resolve a SchedClass at runtime, where SchedClass identifies an 139 /// MCSchedClassDesc with the isVariant property. This may return the ID of 140 /// another variant SchedClass, but repeated invocation must quickly terminate 141 /// in a nonvariant SchedClass. resolveSchedClass(unsigned SchedClass,const MachineInstr * MI,const TargetSchedModel * SchedModel)142 virtual unsigned resolveSchedClass(unsigned SchedClass, 143 const MachineInstr *MI, 144 const TargetSchedModel *SchedModel) const { 145 return 0; 146 } 147 148 /// Returns true if MI is a dependency breaking zero-idiom instruction for the 149 /// subtarget. 150 /// 151 /// This function also sets bits in Mask related to input operands that 152 /// are not in a data dependency relationship. There is one bit for each 153 /// machine operand; implicit operands follow explicit operands in the bit 154 /// representation used for Mask. An empty (i.e. a mask with all bits 155 /// cleared) means: data dependencies are "broken" for all the explicit input 156 /// machine operands of MI. isZeroIdiom(const MachineInstr * MI,APInt & Mask)157 virtual bool isZeroIdiom(const MachineInstr *MI, APInt &Mask) const { 158 return false; 159 } 160 161 /// Returns true if MI is a dependency breaking instruction for the subtarget. 162 /// 163 /// Similar in behavior to `isZeroIdiom`. However, it knows how to identify 164 /// all dependency breaking instructions (i.e. not just zero-idioms). 165 /// 166 /// As for `isZeroIdiom`, this method returns a mask of "broken" dependencies. 167 /// (See method `isZeroIdiom` for a detailed description of Mask). isDependencyBreaking(const MachineInstr * MI,APInt & Mask)168 virtual bool isDependencyBreaking(const MachineInstr *MI, APInt &Mask) const { 169 return isZeroIdiom(MI, Mask); 170 } 171 172 /// Returns true if MI is a candidate for move elimination. 173 /// 174 /// A candidate for move elimination may be optimized out at register renaming 175 /// stage. Subtargets can specify the set of optimizable moves by 176 /// instantiating tablegen class `IsOptimizableRegisterMove` (see 177 /// llvm/Target/TargetInstrPredicate.td). 178 /// 179 /// SubtargetEmitter is responsible for processing all the definitions of class 180 /// IsOptimizableRegisterMove, and auto-generate an override for this method. isOptimizableRegisterMove(const MachineInstr * MI)181 virtual bool isOptimizableRegisterMove(const MachineInstr *MI) const { 182 return false; 183 } 184 185 /// True if the subtarget should run MachineScheduler after aggressive 186 /// coalescing. 187 /// 188 /// This currently replaces the SelectionDAG scheduler with the "source" order 189 /// scheduler (though see below for an option to turn this off and use the 190 /// TargetLowering preference). It does not yet disable the postRA scheduler. 191 virtual bool enableMachineScheduler() const; 192 193 /// Support printing of [latency:throughput] comment in output .S file. supportPrintSchedInfo()194 virtual bool supportPrintSchedInfo() const { return false; } 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 enable joining global copies. 201 /// 202 /// By default this is enabled if the machine scheduler is enabled, but 203 /// can be overridden. 204 virtual bool enableJoinGlobalCopies() const; 205 206 /// True if the subtarget should run a scheduler after register allocation. 207 /// 208 /// By default this queries the PostRAScheduling bit in the scheduling model 209 /// which is the preferred way to influence this. 210 virtual bool enablePostRAScheduler() const; 211 212 /// True if the subtarget should run the atomic expansion pass. 213 virtual bool enableAtomicExpand() const; 214 215 /// True if the subtarget should run the indirectbr expansion pass. 216 virtual bool enableIndirectBrExpand() const; 217 218 /// Override generic scheduling policy within a region. 219 /// 220 /// This is a convenient way for targets that don't provide any custom 221 /// scheduling heuristics (no custom MachineSchedStrategy) to make 222 /// changes to the generic scheduling policy. overrideSchedPolicy(MachineSchedPolicy & Policy,unsigned NumRegionInstrs)223 virtual void overrideSchedPolicy(MachineSchedPolicy &Policy, 224 unsigned NumRegionInstrs) const {} 225 226 // Perform target specific adjustments to the latency of a schedule 227 // dependency. adjustSchedDependency(SUnit * def,SUnit * use,SDep & dep)228 virtual void adjustSchedDependency(SUnit *def, SUnit *use, SDep &dep) const {} 229 230 // For use with PostRAScheduling: get the anti-dependence breaking that should 231 // be performed before post-RA scheduling. getAntiDepBreakMode()232 virtual AntiDepBreakMode getAntiDepBreakMode() const { return ANTIDEP_NONE; } 233 234 // For use with PostRAScheduling: in CriticalPathRCs, return any register 235 // classes that should only be considered for anti-dependence breaking if they 236 // are on the critical path. getCriticalPathRCs(RegClassVector & CriticalPathRCs)237 virtual void getCriticalPathRCs(RegClassVector &CriticalPathRCs) const { 238 return CriticalPathRCs.clear(); 239 } 240 241 // Provide an ordered list of schedule DAG mutations for the post-RA 242 // scheduler. getPostRAMutations(std::vector<std::unique_ptr<ScheduleDAGMutation>> & Mutations)243 virtual void getPostRAMutations( 244 std::vector<std::unique_ptr<ScheduleDAGMutation>> &Mutations) const { 245 } 246 247 // Provide an ordered list of schedule DAG mutations for the machine 248 // pipeliner. getSMSMutations(std::vector<std::unique_ptr<ScheduleDAGMutation>> & Mutations)249 virtual void getSMSMutations( 250 std::vector<std::unique_ptr<ScheduleDAGMutation>> &Mutations) const { 251 } 252 253 // For use with PostRAScheduling: get the minimum optimization level needed 254 // to enable post-RA scheduling. getOptLevelToEnablePostRAScheduler()255 virtual CodeGenOpt::Level getOptLevelToEnablePostRAScheduler() const { 256 return CodeGenOpt::Default; 257 } 258 259 /// True if the subtarget should run the local reassignment 260 /// heuristic of the register allocator. 261 /// This heuristic may be compile time intensive, \p OptLevel provides 262 /// a finer grain to tune the register allocator. 263 virtual bool enableRALocalReassignment(CodeGenOpt::Level OptLevel) const; 264 265 /// True if the subtarget should consider the cost of local intervals 266 /// created by a split candidate when choosing the best split candidate. This 267 /// heuristic may be compile time intensive. 268 virtual bool enableAdvancedRASplitCost() const; 269 270 /// Enable use of alias analysis during code generation (during MI 271 /// scheduling, DAGCombine, etc.). 272 virtual bool useAA() const; 273 274 /// Enable the use of the early if conversion pass. enableEarlyIfConversion()275 virtual bool enableEarlyIfConversion() const { return false; } 276 277 /// Return PBQPConstraint(s) for the target. 278 /// 279 /// Override to provide custom PBQP constraints. getCustomPBQPConstraints()280 virtual std::unique_ptr<PBQPRAConstraint> getCustomPBQPConstraints() const { 281 return nullptr; 282 } 283 284 /// Enable tracking of subregister liveness in register allocator. 285 /// Please use MachineRegisterInfo::subRegLivenessEnabled() instead where 286 /// possible. enableSubRegLiveness()287 virtual bool enableSubRegLiveness() const { return false; } 288 289 /// Returns string representation of scheduler comment 290 std::string getSchedInfoStr(const MachineInstr &MI) const; 291 std::string getSchedInfoStr(MCInst const &MCI) const override; 292 293 /// This is called after a .mir file was loaded. 294 virtual void mirFileLoaded(MachineFunction &MF) const; 295 }; 296 297 } // end namespace llvm 298 299 #endif // LLVM_CODEGEN_TARGETSUBTARGETINFO_H 300