Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 1 | //===- llvm/CodeGen/TargetSubtargetInfo.h - Target Information --*- C++ -*-===// |
| 2 | // |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame^] | 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 |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 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 | |
Andrew Scull | 0372a57 | 2018-11-16 15:47:06 +0000 | [diff] [blame] | 16 | #include "llvm/ADT/APInt.h" |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 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 SubtargetInfoKV; |
| 46 | class SUnit; |
| 47 | class TargetFrameLowering; |
| 48 | class TargetInstrInfo; |
| 49 | class TargetLowering; |
| 50 | class TargetRegisterClass; |
| 51 | class TargetRegisterInfo; |
| 52 | class TargetSchedModel; |
| 53 | class Triple; |
| 54 | |
| 55 | //===----------------------------------------------------------------------===// |
| 56 | /// |
| 57 | /// TargetSubtargetInfo - Generic base class for all target subtargets. All |
| 58 | /// Target-specific options that control code generation and printing should |
| 59 | /// be exposed through a TargetSubtargetInfo-derived class. |
| 60 | /// |
| 61 | class TargetSubtargetInfo : public MCSubtargetInfo { |
| 62 | protected: // Can only create subclasses... |
| 63 | TargetSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS, |
| 64 | ArrayRef<SubtargetFeatureKV> PF, |
| 65 | ArrayRef<SubtargetFeatureKV> PD, |
| 66 | const SubtargetInfoKV *ProcSched, |
| 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 | |
| 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. |
| 95 | virtual const TargetInstrInfo *getInstrInfo() const { return nullptr; } |
| 96 | virtual const TargetFrameLowering *getFrameLowering() const { |
| 97 | return nullptr; |
| 98 | } |
| 99 | virtual const TargetLowering *getTargetLowering() const { return nullptr; } |
| 100 | virtual const SelectionDAGTargetInfo *getSelectionDAGInfo() const { |
| 101 | return nullptr; |
| 102 | } |
| 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. |
| 109 | virtual const InstructionSelector *getInstructionSelector() const { |
| 110 | return nullptr; |
| 111 | } |
| 112 | |
| 113 | virtual unsigned getHwMode() const { return 0; } |
| 114 | |
| 115 | /// Target can subclass this hook to select a different DAG scheduler. |
| 116 | virtual RegisterScheduler::FunctionPassCtor |
| 117 | getDAGScheduler(CodeGenOpt::Level) const { |
| 118 | return nullptr; |
| 119 | } |
| 120 | |
| 121 | virtual const LegalizerInfo *getLegalizerInfo() const { return nullptr; } |
| 122 | |
| 123 | /// getRegisterInfo - If register information is available, return it. If |
| 124 | /// not, return null. |
| 125 | virtual const TargetRegisterInfo *getRegisterInfo() const { return nullptr; } |
| 126 | |
| 127 | /// If the information for the register banks is available, return it. |
| 128 | /// Otherwise return nullptr. |
| 129 | virtual const RegisterBankInfo *getRegBankInfo() const { return nullptr; } |
| 130 | |
| 131 | /// getInstrItineraryData - Returns instruction itinerary data for the target |
| 132 | /// or specific subtarget. |
| 133 | virtual const InstrItineraryData *getInstrItineraryData() const { |
| 134 | return nullptr; |
| 135 | } |
| 136 | |
| 137 | /// Resolve a SchedClass at runtime, where SchedClass identifies an |
| 138 | /// MCSchedClassDesc with the isVariant property. This may return the ID of |
| 139 | /// another variant SchedClass, but repeated invocation must quickly terminate |
| 140 | /// in a nonvariant SchedClass. |
| 141 | virtual unsigned resolveSchedClass(unsigned SchedClass, |
| 142 | const MachineInstr *MI, |
| 143 | const TargetSchedModel *SchedModel) const { |
| 144 | return 0; |
| 145 | } |
| 146 | |
Andrew Scull | 0372a57 | 2018-11-16 15:47:06 +0000 | [diff] [blame] | 147 | /// Returns true if MI is a dependency breaking zero-idiom instruction for the |
| 148 | /// subtarget. |
| 149 | /// |
| 150 | /// This function also sets bits in Mask related to input operands that |
| 151 | /// are not in a data dependency relationship. There is one bit for each |
| 152 | /// machine operand; implicit operands follow explicit operands in the bit |
| 153 | /// representation used for Mask. An empty (i.e. a mask with all bits |
| 154 | /// cleared) means: data dependencies are "broken" for all the explicit input |
| 155 | /// machine operands of MI. |
| 156 | virtual bool isZeroIdiom(const MachineInstr *MI, APInt &Mask) const { |
| 157 | return false; |
| 158 | } |
| 159 | |
| 160 | /// Returns true if MI is a dependency breaking instruction for the subtarget. |
| 161 | /// |
| 162 | /// Similar in behavior to `isZeroIdiom`. However, it knows how to identify |
| 163 | /// all dependency breaking instructions (i.e. not just zero-idioms). |
| 164 | /// |
| 165 | /// As for `isZeroIdiom`, this method returns a mask of "broken" dependencies. |
| 166 | /// (See method `isZeroIdiom` for a detailed description of Mask). |
| 167 | virtual bool isDependencyBreaking(const MachineInstr *MI, APInt &Mask) const { |
| 168 | return isZeroIdiom(MI, Mask); |
| 169 | } |
| 170 | |
Andrew Walbran | 16937d0 | 2019-10-22 13:54:20 +0100 | [diff] [blame^] | 171 | /// Returns true if MI is a candidate for move elimination. |
| 172 | /// |
| 173 | /// A candidate for move elimination may be optimized out at register renaming |
| 174 | /// stage. Subtargets can specify the set of optimizable moves by |
| 175 | /// instantiating tablegen class `IsOptimizableRegisterMove` (see |
| 176 | /// llvm/Target/TargetInstrPredicate.td). |
| 177 | /// |
| 178 | /// SubtargetEmitter is responsible for processing all the definitions of class |
| 179 | /// IsOptimizableRegisterMove, and auto-generate an override for this method. |
| 180 | virtual bool isOptimizableRegisterMove(const MachineInstr *MI) const { |
| 181 | return false; |
| 182 | } |
| 183 | |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 184 | /// True if the subtarget should run MachineScheduler after aggressive |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 185 | /// coalescing. |
| 186 | /// |
| 187 | /// This currently replaces the SelectionDAG scheduler with the "source" order |
| 188 | /// scheduler (though see below for an option to turn this off and use the |
| 189 | /// TargetLowering preference). It does not yet disable the postRA scheduler. |
| 190 | virtual bool enableMachineScheduler() const; |
| 191 | |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 192 | /// True if the machine scheduler should disable the TLI preference |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 193 | /// for preRA scheduling with the source level scheduler. |
| 194 | virtual bool enableMachineSchedDefaultSched() const { return true; } |
| 195 | |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 196 | /// True if the subtarget should enable joining global copies. |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 197 | /// |
| 198 | /// By default this is enabled if the machine scheduler is enabled, but |
| 199 | /// can be overridden. |
| 200 | virtual bool enableJoinGlobalCopies() const; |
| 201 | |
| 202 | /// True if the subtarget should run a scheduler after register allocation. |
| 203 | /// |
| 204 | /// By default this queries the PostRAScheduling bit in the scheduling model |
| 205 | /// which is the preferred way to influence this. |
| 206 | virtual bool enablePostRAScheduler() const; |
| 207 | |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 208 | /// True if the subtarget should run the atomic expansion pass. |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 209 | virtual bool enableAtomicExpand() const; |
| 210 | |
| 211 | /// True if the subtarget should run the indirectbr expansion pass. |
| 212 | virtual bool enableIndirectBrExpand() const; |
| 213 | |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 214 | /// Override generic scheduling policy within a region. |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 215 | /// |
| 216 | /// This is a convenient way for targets that don't provide any custom |
| 217 | /// scheduling heuristics (no custom MachineSchedStrategy) to make |
| 218 | /// changes to the generic scheduling policy. |
| 219 | virtual void overrideSchedPolicy(MachineSchedPolicy &Policy, |
| 220 | unsigned NumRegionInstrs) const {} |
| 221 | |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 222 | // Perform target specific adjustments to the latency of a schedule |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 223 | // dependency. |
| 224 | virtual void adjustSchedDependency(SUnit *def, SUnit *use, SDep &dep) const {} |
| 225 | |
| 226 | // For use with PostRAScheduling: get the anti-dependence breaking that should |
| 227 | // be performed before post-RA scheduling. |
| 228 | virtual AntiDepBreakMode getAntiDepBreakMode() const { return ANTIDEP_NONE; } |
| 229 | |
| 230 | // For use with PostRAScheduling: in CriticalPathRCs, return any register |
| 231 | // classes that should only be considered for anti-dependence breaking if they |
| 232 | // are on the critical path. |
| 233 | virtual void getCriticalPathRCs(RegClassVector &CriticalPathRCs) const { |
| 234 | return CriticalPathRCs.clear(); |
| 235 | } |
| 236 | |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 237 | // Provide an ordered list of schedule DAG mutations for the post-RA |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 238 | // scheduler. |
| 239 | virtual void getPostRAMutations( |
| 240 | std::vector<std::unique_ptr<ScheduleDAGMutation>> &Mutations) const { |
| 241 | } |
| 242 | |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 243 | // Provide an ordered list of schedule DAG mutations for the machine |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 244 | // pipeliner. |
| 245 | virtual void getSMSMutations( |
| 246 | std::vector<std::unique_ptr<ScheduleDAGMutation>> &Mutations) const { |
| 247 | } |
| 248 | |
| 249 | // For use with PostRAScheduling: get the minimum optimization level needed |
| 250 | // to enable post-RA scheduling. |
| 251 | virtual CodeGenOpt::Level getOptLevelToEnablePostRAScheduler() const { |
| 252 | return CodeGenOpt::Default; |
| 253 | } |
| 254 | |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 255 | /// True if the subtarget should run the local reassignment |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 256 | /// heuristic of the register allocator. |
| 257 | /// This heuristic may be compile time intensive, \p OptLevel provides |
| 258 | /// a finer grain to tune the register allocator. |
| 259 | virtual bool enableRALocalReassignment(CodeGenOpt::Level OptLevel) const; |
| 260 | |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 261 | /// True if the subtarget should consider the cost of local intervals |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 262 | /// created by a split candidate when choosing the best split candidate. This |
| 263 | /// heuristic may be compile time intensive. |
| 264 | virtual bool enableAdvancedRASplitCost() const; |
| 265 | |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 266 | /// Enable use of alias analysis during code generation (during MI |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 267 | /// scheduling, DAGCombine, etc.). |
| 268 | virtual bool useAA() const; |
| 269 | |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 270 | /// Enable the use of the early if conversion pass. |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 271 | virtual bool enableEarlyIfConversion() const { return false; } |
| 272 | |
Andrew Scull | cdfcccc | 2018-10-05 20:58:37 +0100 | [diff] [blame] | 273 | /// Return PBQPConstraint(s) for the target. |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 274 | /// |
| 275 | /// Override to provide custom PBQP constraints. |
| 276 | virtual std::unique_ptr<PBQPRAConstraint> getCustomPBQPConstraints() const { |
| 277 | return nullptr; |
| 278 | } |
| 279 | |
| 280 | /// Enable tracking of subregister liveness in register allocator. |
| 281 | /// Please use MachineRegisterInfo::subRegLivenessEnabled() instead where |
| 282 | /// possible. |
| 283 | virtual bool enableSubRegLiveness() const { return false; } |
| 284 | |
Andrew Scull | 5e1ddfa | 2018-08-14 10:06:54 +0100 | [diff] [blame] | 285 | /// This is called after a .mir file was loaded. |
| 286 | virtual void mirFileLoaded(MachineFunction &MF) const; |
| 287 | }; |
| 288 | |
| 289 | } // end namespace llvm |
| 290 | |
| 291 | #endif // LLVM_CODEGEN_TARGETSUBTARGETINFO_H |