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 |