Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 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 | |
Andrew Scull | 0372a57 | 2018-11-16 15:47:06 +0000 | [diff] [blame] | 17 | #include "llvm/ADT/APInt.h" |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 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 | |
| 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. |
| 96 | virtual const TargetInstrInfo *getInstrInfo() const { return nullptr; } |
| 97 | virtual const TargetFrameLowering *getFrameLowering() const { |
| 98 | return nullptr; |
| 99 | } |
| 100 | virtual const TargetLowering *getTargetLowering() const { return nullptr; } |
| 101 | virtual const SelectionDAGTargetInfo *getSelectionDAGInfo() const { |
| 102 | return nullptr; |
| 103 | } |
| 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. |
| 110 | virtual const InstructionSelector *getInstructionSelector() const { |
| 111 | return nullptr; |
| 112 | } |
| 113 | |
| 114 | virtual unsigned getHwMode() const { return 0; } |
| 115 | |
| 116 | /// Target can subclass this hook to select a different DAG scheduler. |
| 117 | virtual RegisterScheduler::FunctionPassCtor |
| 118 | getDAGScheduler(CodeGenOpt::Level) const { |
| 119 | return nullptr; |
| 120 | } |
| 121 | |
| 122 | virtual const LegalizerInfo *getLegalizerInfo() const { return nullptr; } |
| 123 | |
| 124 | /// getRegisterInfo - If register information is available, return it. If |
| 125 | /// not, return null. |
| 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. |
| 130 | virtual const RegisterBankInfo *getRegBankInfo() const { return nullptr; } |
| 131 | |
| 132 | /// getInstrItineraryData - Returns instruction itinerary data for the target |
| 133 | /// or specific subtarget. |
| 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. |
| 142 | virtual unsigned resolveSchedClass(unsigned SchedClass, |
| 143 | const MachineInstr *MI, |
| 144 | const TargetSchedModel *SchedModel) const { |
| 145 | return 0; |
| 146 | } |
| 147 | |
Andrew Scull | 0372a57 | 2018-11-16 15:47:06 +0000 | [diff] [blame] | 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. |
| 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). |
| 168 | virtual bool isDependencyBreaking(const MachineInstr *MI, APInt &Mask) const { |
| 169 | return isZeroIdiom(MI, Mask); |
| 170 | } |
| 171 | |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 172 | /// True if the subtarget should run MachineScheduler after aggressive |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 173 | /// coalescing. |
| 174 | /// |
| 175 | /// This currently replaces the SelectionDAG scheduler with the "source" order |
| 176 | /// scheduler (though see below for an option to turn this off and use the |
| 177 | /// TargetLowering preference). It does not yet disable the postRA scheduler. |
| 178 | virtual bool enableMachineScheduler() const; |
| 179 | |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 180 | /// Support printing of [latency:throughput] comment in output .S file. |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 181 | virtual bool supportPrintSchedInfo() const { return false; } |
| 182 | |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 183 | /// True if the machine scheduler should disable the TLI preference |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 184 | /// for preRA scheduling with the source level scheduler. |
| 185 | virtual bool enableMachineSchedDefaultSched() const { return true; } |
| 186 | |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 187 | /// True if the subtarget should enable joining global copies. |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 188 | /// |
| 189 | /// By default this is enabled if the machine scheduler is enabled, but |
| 190 | /// can be overridden. |
| 191 | virtual bool enableJoinGlobalCopies() const; |
| 192 | |
| 193 | /// True if the subtarget should run a scheduler after register allocation. |
| 194 | /// |
| 195 | /// By default this queries the PostRAScheduling bit in the scheduling model |
| 196 | /// which is the preferred way to influence this. |
| 197 | virtual bool enablePostRAScheduler() const; |
| 198 | |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 199 | /// True if the subtarget should run the atomic expansion pass. |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 200 | virtual bool enableAtomicExpand() const; |
| 201 | |
| 202 | /// True if the subtarget should run the indirectbr expansion pass. |
| 203 | virtual bool enableIndirectBrExpand() const; |
| 204 | |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 205 | /// Override generic scheduling policy within a region. |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 206 | /// |
| 207 | /// This is a convenient way for targets that don't provide any custom |
| 208 | /// scheduling heuristics (no custom MachineSchedStrategy) to make |
| 209 | /// changes to the generic scheduling policy. |
| 210 | virtual void overrideSchedPolicy(MachineSchedPolicy &Policy, |
| 211 | unsigned NumRegionInstrs) const {} |
| 212 | |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 213 | // Perform target specific adjustments to the latency of a schedule |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 214 | // dependency. |
| 215 | virtual void adjustSchedDependency(SUnit *def, SUnit *use, SDep &dep) const {} |
| 216 | |
| 217 | // For use with PostRAScheduling: get the anti-dependence breaking that should |
| 218 | // be performed before post-RA scheduling. |
| 219 | virtual AntiDepBreakMode getAntiDepBreakMode() const { return ANTIDEP_NONE; } |
| 220 | |
| 221 | // For use with PostRAScheduling: in CriticalPathRCs, return any register |
| 222 | // classes that should only be considered for anti-dependence breaking if they |
| 223 | // are on the critical path. |
| 224 | virtual void getCriticalPathRCs(RegClassVector &CriticalPathRCs) const { |
| 225 | return CriticalPathRCs.clear(); |
| 226 | } |
| 227 | |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 228 | // Provide an ordered list of schedule DAG mutations for the post-RA |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 229 | // scheduler. |
| 230 | virtual void getPostRAMutations( |
| 231 | std::vector<std::unique_ptr<ScheduleDAGMutation>> &Mutations) const { |
| 232 | } |
| 233 | |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 234 | // Provide an ordered list of schedule DAG mutations for the machine |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 235 | // pipeliner. |
| 236 | virtual void getSMSMutations( |
| 237 | std::vector<std::unique_ptr<ScheduleDAGMutation>> &Mutations) const { |
| 238 | } |
| 239 | |
| 240 | // For use with PostRAScheduling: get the minimum optimization level needed |
| 241 | // to enable post-RA scheduling. |
| 242 | virtual CodeGenOpt::Level getOptLevelToEnablePostRAScheduler() const { |
| 243 | return CodeGenOpt::Default; |
| 244 | } |
| 245 | |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 246 | /// True if the subtarget should run the local reassignment |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 247 | /// heuristic of the register allocator. |
| 248 | /// This heuristic may be compile time intensive, \p OptLevel provides |
| 249 | /// a finer grain to tune the register allocator. |
| 250 | virtual bool enableRALocalReassignment(CodeGenOpt::Level OptLevel) const; |
| 251 | |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 252 | /// True if the subtarget should consider the cost of local intervals |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 253 | /// created by a split candidate when choosing the best split candidate. This |
| 254 | /// heuristic may be compile time intensive. |
| 255 | virtual bool enableAdvancedRASplitCost() const; |
| 256 | |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 257 | /// Enable use of alias analysis during code generation (during MI |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 258 | /// scheduling, DAGCombine, etc.). |
| 259 | virtual bool useAA() const; |
| 260 | |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 261 | /// Enable the use of the early if conversion pass. |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 262 | virtual bool enableEarlyIfConversion() const { return false; } |
| 263 | |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 264 | /// Return PBQPConstraint(s) for the target. |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 265 | /// |
| 266 | /// Override to provide custom PBQP constraints. |
| 267 | virtual std::unique_ptr<PBQPRAConstraint> getCustomPBQPConstraints() const { |
| 268 | return nullptr; |
| 269 | } |
| 270 | |
| 271 | /// Enable tracking of subregister liveness in register allocator. |
| 272 | /// Please use MachineRegisterInfo::subRegLivenessEnabled() instead where |
| 273 | /// possible. |
| 274 | virtual bool enableSubRegLiveness() const { return false; } |
| 275 | |
| 276 | /// Returns string representation of scheduler comment |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 277 | std::string getSchedInfoStr(const MachineInstr &MI) const; |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 278 | std::string getSchedInfoStr(MCInst const &MCI) const override; |
| 279 | |
| 280 | /// This is called after a .mir file was loaded. |
| 281 | virtual void mirFileLoaded(MachineFunction &MF) const; |
| 282 | }; |
| 283 | |
| 284 | } // end namespace llvm |
| 285 | |
| 286 | #endif // LLVM_CODEGEN_TARGETSUBTARGETINFO_H |