Details | Last modification | View Log | RSS feed
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 14 | pmbaty | 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/PBQPRAConstraint.h" |
||
| 20 | #include "llvm/CodeGen/SchedulerRegistry.h" |
||
| 21 | #include "llvm/IR/GlobalValue.h" |
||
| 22 | #include "llvm/MC/MCSubtargetInfo.h" |
||
| 23 | #include "llvm/Support/CodeGen.h" |
||
| 24 | #include <memory> |
||
| 25 | #include <vector> |
||
| 26 | |||
| 27 | namespace llvm { |
||
| 28 | |||
| 29 | class APInt; |
||
| 30 | class MachineFunction; |
||
| 31 | class ScheduleDAGMutation; |
||
| 32 | class CallLowering; |
||
| 33 | class GlobalValue; |
||
| 34 | class InlineAsmLowering; |
||
| 35 | class InstrItineraryData; |
||
| 36 | struct InstrStage; |
||
| 37 | class InstructionSelector; |
||
| 38 | class LegalizerInfo; |
||
| 39 | class MachineInstr; |
||
| 40 | struct MachineSchedPolicy; |
||
| 41 | struct MCReadAdvanceEntry; |
||
| 42 | struct MCWriteLatencyEntry; |
||
| 43 | struct MCWriteProcResEntry; |
||
| 44 | class RegisterBankInfo; |
||
| 45 | class SDep; |
||
| 46 | class SelectionDAGTargetInfo; |
||
| 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 TuneCPU, |
||
| 65 | StringRef FS, 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 | |||
| 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 | virtual const InlineAsmLowering *getInlineAsmLowering() const { |
||
| 106 | return nullptr; |
||
| 107 | } |
||
| 108 | |||
| 109 | // FIXME: This lets targets specialize the selector by subtarget (which lets |
||
| 110 | // us do things like a dedicated avx512 selector). However, we might want |
||
| 111 | // to also specialize selectors by MachineFunction, which would let us be |
||
| 112 | // aware of optsize/optnone and such. |
||
| 113 | virtual InstructionSelector *getInstructionSelector() const { |
||
| 114 | return nullptr; |
||
| 115 | } |
||
| 116 | |||
| 117 | /// Target can subclass this hook to select a different DAG scheduler. |
||
| 118 | virtual RegisterScheduler::FunctionPassCtor |
||
| 119 | getDAGScheduler(CodeGenOpt::Level) const { |
||
| 120 | return nullptr; |
||
| 121 | } |
||
| 122 | |||
| 123 | virtual const LegalizerInfo *getLegalizerInfo() const { return nullptr; } |
||
| 124 | |||
| 125 | /// getRegisterInfo - If register information is available, return it. If |
||
| 126 | /// not, return null. |
||
| 127 | virtual const TargetRegisterInfo *getRegisterInfo() const { return nullptr; } |
||
| 128 | |||
| 129 | /// If the information for the register banks is available, return it. |
||
| 130 | /// Otherwise return nullptr. |
||
| 131 | virtual const RegisterBankInfo *getRegBankInfo() const { return nullptr; } |
||
| 132 | |||
| 133 | /// getInstrItineraryData - Returns instruction itinerary data for the target |
||
| 134 | /// or specific subtarget. |
||
| 135 | virtual const InstrItineraryData *getInstrItineraryData() const { |
||
| 136 | return nullptr; |
||
| 137 | } |
||
| 138 | |||
| 139 | /// Resolve a SchedClass at runtime, where SchedClass identifies an |
||
| 140 | /// MCSchedClassDesc with the isVariant property. This may return the ID of |
||
| 141 | /// another variant SchedClass, but repeated invocation must quickly terminate |
||
| 142 | /// in a nonvariant SchedClass. |
||
| 143 | virtual unsigned resolveSchedClass(unsigned SchedClass, |
||
| 144 | const MachineInstr *MI, |
||
| 145 | const TargetSchedModel *SchedModel) const { |
||
| 146 | return 0; |
||
| 147 | } |
||
| 148 | |||
| 149 | /// Returns true if MI is a dependency breaking zero-idiom instruction for the |
||
| 150 | /// subtarget. |
||
| 151 | /// |
||
| 152 | /// This function also sets bits in Mask related to input operands that |
||
| 153 | /// are not in a data dependency relationship. There is one bit for each |
||
| 154 | /// machine operand; implicit operands follow explicit operands in the bit |
||
| 155 | /// representation used for Mask. An empty (i.e. a mask with all bits |
||
| 156 | /// cleared) means: data dependencies are "broken" for all the explicit input |
||
| 157 | /// machine operands of MI. |
||
| 158 | virtual bool isZeroIdiom(const MachineInstr *MI, APInt &Mask) const { |
||
| 159 | return false; |
||
| 160 | } |
||
| 161 | |||
| 162 | /// Returns true if MI is a dependency breaking instruction for the subtarget. |
||
| 163 | /// |
||
| 164 | /// Similar in behavior to `isZeroIdiom`. However, it knows how to identify |
||
| 165 | /// all dependency breaking instructions (i.e. not just zero-idioms). |
||
| 166 | /// |
||
| 167 | /// As for `isZeroIdiom`, this method returns a mask of "broken" dependencies. |
||
| 168 | /// (See method `isZeroIdiom` for a detailed description of Mask). |
||
| 169 | virtual bool isDependencyBreaking(const MachineInstr *MI, APInt &Mask) const { |
||
| 170 | return isZeroIdiom(MI, Mask); |
||
| 171 | } |
||
| 172 | |||
| 173 | /// Returns true if MI is a candidate for move elimination. |
||
| 174 | /// |
||
| 175 | /// A candidate for move elimination may be optimized out at register renaming |
||
| 176 | /// stage. Subtargets can specify the set of optimizable moves by |
||
| 177 | /// instantiating tablegen class `IsOptimizableRegisterMove` (see |
||
| 178 | /// llvm/Target/TargetInstrPredicate.td). |
||
| 179 | /// |
||
| 180 | /// SubtargetEmitter is responsible for processing all the definitions of class |
||
| 181 | /// IsOptimizableRegisterMove, and auto-generate an override for this method. |
||
| 182 | virtual bool isOptimizableRegisterMove(const MachineInstr *MI) const { |
||
| 183 | return false; |
||
| 184 | } |
||
| 185 | |||
| 186 | /// True if the subtarget should run MachineScheduler after aggressive |
||
| 187 | /// coalescing. |
||
| 188 | /// |
||
| 189 | /// This currently replaces the SelectionDAG scheduler with the "source" order |
||
| 190 | /// scheduler (though see below for an option to turn this off and use the |
||
| 191 | /// TargetLowering preference). It does not yet disable the postRA scheduler. |
||
| 192 | virtual bool enableMachineScheduler() const; |
||
| 193 | |||
| 194 | /// True if the machine scheduler should disable the TLI preference |
||
| 195 | /// for preRA scheduling with the source level scheduler. |
||
| 196 | virtual bool enableMachineSchedDefaultSched() const { return true; } |
||
| 197 | |||
| 198 | /// True if the subtarget should run MachinePipeliner |
||
| 199 | virtual bool enableMachinePipeliner() const { return true; }; |
||
| 200 | |||
| 201 | /// True if the subtarget should enable joining global copies. |
||
| 202 | /// |
||
| 203 | /// By default this is enabled if the machine scheduler is enabled, but |
||
| 204 | /// can be overridden. |
||
| 205 | virtual bool enableJoinGlobalCopies() const; |
||
| 206 | |||
| 207 | /// True if the subtarget should run a scheduler after register allocation. |
||
| 208 | /// |
||
| 209 | /// By default this queries the PostRAScheduling bit in the scheduling model |
||
| 210 | /// which is the preferred way to influence this. |
||
| 211 | virtual bool enablePostRAScheduler() const; |
||
| 212 | |||
| 213 | /// True if the subtarget should run a machine scheduler after register |
||
| 214 | /// allocation. |
||
| 215 | virtual bool enablePostRAMachineScheduler() const; |
||
| 216 | |||
| 217 | /// True if the subtarget should run the atomic expansion pass. |
||
| 218 | virtual bool enableAtomicExpand() const; |
||
| 219 | |||
| 220 | /// True if the subtarget should run the indirectbr expansion pass. |
||
| 221 | virtual bool enableIndirectBrExpand() const; |
||
| 222 | |||
| 223 | /// Override generic scheduling policy within a region. |
||
| 224 | /// |
||
| 225 | /// This is a convenient way for targets that don't provide any custom |
||
| 226 | /// scheduling heuristics (no custom MachineSchedStrategy) to make |
||
| 227 | /// changes to the generic scheduling policy. |
||
| 228 | virtual void overrideSchedPolicy(MachineSchedPolicy &Policy, |
||
| 229 | unsigned NumRegionInstrs) const {} |
||
| 230 | |||
| 231 | // Perform target-specific adjustments to the latency of a schedule |
||
| 232 | // dependency. |
||
| 233 | // If a pair of operands is associated with the schedule dependency, DefOpIdx |
||
| 234 | // and UseOpIdx are the indices of the operands in Def and Use, respectively. |
||
| 235 | // Otherwise, either may be -1. |
||
| 236 | virtual void adjustSchedDependency(SUnit *Def, int DefOpIdx, SUnit *Use, |
||
| 237 | int UseOpIdx, SDep &Dep) const {} |
||
| 238 | |||
| 239 | // For use with PostRAScheduling: get the anti-dependence breaking that should |
||
| 240 | // be performed before post-RA scheduling. |
||
| 241 | virtual AntiDepBreakMode getAntiDepBreakMode() const { return ANTIDEP_NONE; } |
||
| 242 | |||
| 243 | // For use with PostRAScheduling: in CriticalPathRCs, return any register |
||
| 244 | // classes that should only be considered for anti-dependence breaking if they |
||
| 245 | // are on the critical path. |
||
| 246 | virtual void getCriticalPathRCs(RegClassVector &CriticalPathRCs) const { |
||
| 247 | return CriticalPathRCs.clear(); |
||
| 248 | } |
||
| 249 | |||
| 250 | // Provide an ordered list of schedule DAG mutations for the post-RA |
||
| 251 | // scheduler. |
||
| 252 | virtual void getPostRAMutations( |
||
| 253 | std::vector<std::unique_ptr<ScheduleDAGMutation>> &Mutations) const { |
||
| 254 | } |
||
| 255 | |||
| 256 | // Provide an ordered list of schedule DAG mutations for the machine |
||
| 257 | // pipeliner. |
||
| 258 | virtual void getSMSMutations( |
||
| 259 | std::vector<std::unique_ptr<ScheduleDAGMutation>> &Mutations) const { |
||
| 260 | } |
||
| 261 | |||
| 262 | /// Default to DFA for resource management, return false when target will use |
||
| 263 | /// ProcResource in InstrSchedModel instead. |
||
| 264 | virtual bool useDFAforSMS() const { return true; } |
||
| 265 | |||
| 266 | // For use with PostRAScheduling: get the minimum optimization level needed |
||
| 267 | // to enable post-RA scheduling. |
||
| 268 | virtual CodeGenOpt::Level getOptLevelToEnablePostRAScheduler() const { |
||
| 269 | return CodeGenOpt::Default; |
||
| 270 | } |
||
| 271 | |||
| 272 | /// True if the subtarget should run the local reassignment |
||
| 273 | /// heuristic of the register allocator. |
||
| 274 | /// This heuristic may be compile time intensive, \p OptLevel provides |
||
| 275 | /// a finer grain to tune the register allocator. |
||
| 276 | virtual bool enableRALocalReassignment(CodeGenOpt::Level OptLevel) const; |
||
| 277 | |||
| 278 | /// Enable use of alias analysis during code generation (during MI |
||
| 279 | /// scheduling, DAGCombine, etc.). |
||
| 280 | virtual bool useAA() const; |
||
| 281 | |||
| 282 | /// \brief Sink addresses into blocks using GEP instructions rather than |
||
| 283 | /// pointer casts and arithmetic. |
||
| 284 | virtual bool addrSinkUsingGEPs() const { |
||
| 285 | return useAA(); |
||
| 286 | } |
||
| 287 | |||
| 288 | /// Enable the use of the early if conversion pass. |
||
| 289 | virtual bool enableEarlyIfConversion() const { return false; } |
||
| 290 | |||
| 291 | /// Return PBQPConstraint(s) for the target. |
||
| 292 | /// |
||
| 293 | /// Override to provide custom PBQP constraints. |
||
| 294 | virtual std::unique_ptr<PBQPRAConstraint> getCustomPBQPConstraints() const { |
||
| 295 | return nullptr; |
||
| 296 | } |
||
| 297 | |||
| 298 | /// Enable tracking of subregister liveness in register allocator. |
||
| 299 | /// Please use MachineRegisterInfo::subRegLivenessEnabled() instead where |
||
| 300 | /// possible. |
||
| 301 | virtual bool enableSubRegLiveness() const { return false; } |
||
| 302 | |||
| 303 | /// This is called after a .mir file was loaded. |
||
| 304 | virtual void mirFileLoaded(MachineFunction &MF) const; |
||
| 305 | |||
| 306 | /// True if the register allocator should use the allocation orders exactly as |
||
| 307 | /// written in the tablegen descriptions, false if it should allocate |
||
| 308 | /// the specified physical register later if is it callee-saved. |
||
| 309 | virtual bool ignoreCSRForAllocationOrder(const MachineFunction &MF, |
||
| 310 | unsigned PhysReg) const { |
||
| 311 | return false; |
||
| 312 | } |
||
| 313 | |||
| 314 | /// Classify a global function reference. This mainly used to fetch target |
||
| 315 | /// special flags for lowering a function address. For example mark a function |
||
| 316 | /// call should be plt or pc-related addressing. |
||
| 317 | virtual unsigned char |
||
| 318 | classifyGlobalFunctionReference(const GlobalValue *GV) const { |
||
| 319 | return 0; |
||
| 320 | } |
||
| 321 | }; |
||
| 322 | |||
| 323 | } // end namespace llvm |
||
| 324 | |||
| 325 | #endif // LLVM_CODEGEN_TARGETSUBTARGETINFO_H |