Home | History | Annotate | Line # | Download | only in CodeGen
      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/APInt.h"
     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 namespace llvm {
     29 
     30 class CallLowering;
     31 class InlineAsmLowering;
     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 class SUnit;
     45 class TargetFrameLowering;
     46 class TargetInstrInfo;
     47 class TargetLowering;
     48 class TargetRegisterClass;
     49 class TargetRegisterInfo;
     50 class TargetSchedModel;
     51 class Triple;
     52 
     53 //===----------------------------------------------------------------------===//
     54 ///
     55 /// TargetSubtargetInfo - Generic base class for all target subtargets.  All
     56 /// Target-specific options that control code generation and printing should
     57 /// be exposed through a TargetSubtargetInfo-derived class.
     58 ///
     59 class TargetSubtargetInfo : public MCSubtargetInfo {
     60 protected: // Can only create subclasses...
     61   TargetSubtargetInfo(const Triple &TT, StringRef CPU, StringRef TuneCPU,
     62                       StringRef FS, ArrayRef<SubtargetFeatureKV> PF,
     63                       ArrayRef<SubtargetSubTypeKV> PD,
     64                       const MCWriteProcResEntry *WPR,
     65                       const MCWriteLatencyEntry *WL,
     66                       const MCReadAdvanceEntry *RA, const InstrStage *IS,
     67                       const unsigned *OC, const unsigned *FP);
     68 
     69 public:
     70   // AntiDepBreakMode - Type of anti-dependence breaking that should
     71   // be performed before post-RA scheduling.
     72   using AntiDepBreakMode = enum { ANTIDEP_NONE, ANTIDEP_CRITICAL, ANTIDEP_ALL };
     73   using RegClassVector = SmallVectorImpl<const TargetRegisterClass *>;
     74 
     75   TargetSubtargetInfo() = delete;
     76   TargetSubtargetInfo(const TargetSubtargetInfo &) = delete;
     77   TargetSubtargetInfo &operator=(const TargetSubtargetInfo &) = delete;
     78   ~TargetSubtargetInfo() override;
     79 
     80   virtual bool isXRaySupported() const { return false; }
     81 
     82   // Interfaces to the major aspects of target machine information:
     83   //
     84   // -- Instruction opcode and operand information
     85   // -- Pipelines and scheduling information
     86   // -- Stack frame information
     87   // -- Selection DAG lowering information
     88   // -- Call lowering information
     89   //
     90   // N.B. These objects may change during compilation. It's not safe to cache
     91   // them between functions.
     92   virtual const TargetInstrInfo *getInstrInfo() const { return nullptr; }
     93   virtual const TargetFrameLowering *getFrameLowering() const {
     94     return nullptr;
     95   }
     96   virtual const TargetLowering *getTargetLowering() const { return nullptr; }
     97   virtual const SelectionDAGTargetInfo *getSelectionDAGInfo() const {
     98     return nullptr;
     99   }
    100   virtual const CallLowering *getCallLowering() const { return nullptr; }
    101 
    102   virtual const InlineAsmLowering *getInlineAsmLowering() const {
    103     return nullptr;
    104   }
    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 InstructionSelector *getInstructionSelector() const {
    111     return nullptr;
    112   }
    113 
    114   /// Target can subclass this hook to select a different DAG scheduler.
    115   virtual RegisterScheduler::FunctionPassCtor
    116       getDAGScheduler(CodeGenOpt::Level) const {
    117     return nullptr;
    118   }
    119 
    120   virtual const LegalizerInfo *getLegalizerInfo() const { return nullptr; }
    121 
    122   /// getRegisterInfo - If register information is available, return it.  If
    123   /// not, return null.
    124   virtual const TargetRegisterInfo *getRegisterInfo() const { return nullptr; }
    125 
    126   /// If the information for the register banks is available, return it.
    127   /// Otherwise return nullptr.
    128   virtual const RegisterBankInfo *getRegBankInfo() const { return nullptr; }
    129 
    130   /// getInstrItineraryData - Returns instruction itinerary data for the target
    131   /// or specific subtarget.
    132   virtual const InstrItineraryData *getInstrItineraryData() const {
    133     return nullptr;
    134   }
    135 
    136   /// Resolve a SchedClass at runtime, where SchedClass identifies an
    137   /// MCSchedClassDesc with the isVariant property. This may return the ID of
    138   /// another variant SchedClass, but repeated invocation must quickly terminate
    139   /// in a nonvariant SchedClass.
    140   virtual unsigned resolveSchedClass(unsigned SchedClass,
    141                                      const MachineInstr *MI,
    142                                      const TargetSchedModel *SchedModel) const {
    143     return 0;
    144   }
    145 
    146   /// Returns true if MI is a dependency breaking zero-idiom instruction for the
    147   /// subtarget.
    148   ///
    149   /// This function also sets bits in Mask related to input operands that
    150   /// are not in a data dependency relationship.  There is one bit for each
    151   /// machine operand; implicit operands follow explicit operands in the bit
    152   /// representation used for Mask.  An empty (i.e. a mask with all bits
    153   /// cleared) means: data dependencies are "broken" for all the explicit input
    154   /// machine operands of MI.
    155   virtual bool isZeroIdiom(const MachineInstr *MI, APInt &Mask) const {
    156     return false;
    157   }
    158 
    159   /// Returns true if MI is a dependency breaking instruction for the subtarget.
    160   ///
    161   /// Similar in behavior to `isZeroIdiom`. However, it knows how to identify
    162   /// all dependency breaking instructions (i.e. not just zero-idioms).
    163   ///
    164   /// As for `isZeroIdiom`, this method returns a mask of "broken" dependencies.
    165   /// (See method `isZeroIdiom` for a detailed description of Mask).
    166   virtual bool isDependencyBreaking(const MachineInstr *MI, APInt &Mask) const {
    167     return isZeroIdiom(MI, Mask);
    168   }
    169 
    170   /// Returns true if MI is a candidate for move elimination.
    171   ///
    172   /// A candidate for move elimination may be optimized out at register renaming
    173   /// stage. Subtargets can specify the set of optimizable moves by
    174   /// instantiating tablegen class `IsOptimizableRegisterMove` (see
    175   /// llvm/Target/TargetInstrPredicate.td).
    176   ///
    177   /// SubtargetEmitter is responsible for processing all the definitions of class
    178   /// IsOptimizableRegisterMove, and auto-generate an override for this method.
    179   virtual bool isOptimizableRegisterMove(const MachineInstr *MI) const {
    180     return false;
    181   }
    182 
    183   /// True if the subtarget should run MachineScheduler after aggressive
    184   /// coalescing.
    185   ///
    186   /// This currently replaces the SelectionDAG scheduler with the "source" order
    187   /// scheduler (though see below for an option to turn this off and use the
    188   /// TargetLowering preference). It does not yet disable the postRA scheduler.
    189   virtual bool enableMachineScheduler() const;
    190 
    191   /// True if the machine scheduler should disable the TLI preference
    192   /// for preRA scheduling with the source level scheduler.
    193   virtual bool enableMachineSchedDefaultSched() const { return true; }
    194 
    195   /// True if the subtarget should run MachinePipeliner
    196   virtual bool enableMachinePipeliner() const { return true; };
    197 
    198   /// True if the subtarget should enable joining global copies.
    199   ///
    200   /// By default this is enabled if the machine scheduler is enabled, but
    201   /// can be overridden.
    202   virtual bool enableJoinGlobalCopies() const;
    203 
    204   /// True if the subtarget should run a scheduler after register allocation.
    205   ///
    206   /// By default this queries the PostRAScheduling bit in the scheduling model
    207   /// which is the preferred way to influence this.
    208   virtual bool enablePostRAScheduler() const;
    209 
    210   /// True if the subtarget should run a machine scheduler after register
    211   /// allocation.
    212   virtual bool enablePostRAMachineScheduler() const;
    213 
    214   /// True if the subtarget should run the atomic expansion pass.
    215   virtual bool enableAtomicExpand() const;
    216 
    217   /// True if the subtarget should run the indirectbr expansion pass.
    218   virtual bool enableIndirectBrExpand() const;
    219 
    220   /// Override generic scheduling policy within a region.
    221   ///
    222   /// This is a convenient way for targets that don't provide any custom
    223   /// scheduling heuristics (no custom MachineSchedStrategy) to make
    224   /// changes to the generic scheduling policy.
    225   virtual void overrideSchedPolicy(MachineSchedPolicy &Policy,
    226                                    unsigned NumRegionInstrs) const {}
    227 
    228   // Perform target-specific adjustments to the latency of a schedule
    229   // dependency.
    230   // If a pair of operands is associated with the schedule dependency, DefOpIdx
    231   // and UseOpIdx are the indices of the operands in Def and Use, respectively.
    232   // Otherwise, either may be -1.
    233   virtual void adjustSchedDependency(SUnit *Def, int DefOpIdx, SUnit *Use,
    234                                      int UseOpIdx, SDep &Dep) const {}
    235 
    236   // For use with PostRAScheduling: get the anti-dependence breaking that should
    237   // be performed before post-RA scheduling.
    238   virtual AntiDepBreakMode getAntiDepBreakMode() const { return ANTIDEP_NONE; }
    239 
    240   // For use with PostRAScheduling: in CriticalPathRCs, return any register
    241   // classes that should only be considered for anti-dependence breaking if they
    242   // are on the critical path.
    243   virtual void getCriticalPathRCs(RegClassVector &CriticalPathRCs) const {
    244     return CriticalPathRCs.clear();
    245   }
    246 
    247   // Provide an ordered list of schedule DAG mutations for the post-RA
    248   // scheduler.
    249   virtual void getPostRAMutations(
    250       std::vector<std::unique_ptr<ScheduleDAGMutation>> &Mutations) const {
    251   }
    252 
    253   // Provide an ordered list of schedule DAG mutations for the machine
    254   // pipeliner.
    255   virtual void getSMSMutations(
    256       std::vector<std::unique_ptr<ScheduleDAGMutation>> &Mutations) const {
    257   }
    258 
    259   /// Default to DFA for resource management, return false when target will use
    260   /// ProcResource in InstrSchedModel instead.
    261   virtual bool useDFAforSMS() const { return true; }
    262 
    263   // For use with PostRAScheduling: get the minimum optimization level needed
    264   // to enable post-RA scheduling.
    265   virtual CodeGenOpt::Level getOptLevelToEnablePostRAScheduler() const {
    266     return CodeGenOpt::Default;
    267   }
    268 
    269   /// True if the subtarget should run the local reassignment
    270   /// heuristic of the register allocator.
    271   /// This heuristic may be compile time intensive, \p OptLevel provides
    272   /// a finer grain to tune the register allocator.
    273   virtual bool enableRALocalReassignment(CodeGenOpt::Level OptLevel) const;
    274 
    275   /// True if the subtarget should consider the cost of local intervals
    276   /// created by a split candidate when choosing the best split candidate. This
    277   /// heuristic may be compile time intensive.
    278   virtual bool enableAdvancedRASplitCost() const;
    279 
    280   /// Enable use of alias analysis during code generation (during MI
    281   /// scheduling, DAGCombine, etc.).
    282   virtual bool useAA() const;
    283 
    284   /// \brief Sink addresses into blocks using GEP instructions rather than
    285   /// pointer casts and arithmetic.
    286   virtual bool addrSinkUsingGEPs() const {
    287     return useAA();
    288   }
    289 
    290   /// Enable the use of the early if conversion pass.
    291   virtual bool enableEarlyIfConversion() const { return false; }
    292 
    293   /// Return PBQPConstraint(s) for the target.
    294   ///
    295   /// Override to provide custom PBQP constraints.
    296   virtual std::unique_ptr<PBQPRAConstraint> getCustomPBQPConstraints() const {
    297     return nullptr;
    298   }
    299 
    300   /// Enable tracking of subregister liveness in register allocator.
    301   /// Please use MachineRegisterInfo::subRegLivenessEnabled() instead where
    302   /// possible.
    303   virtual bool enableSubRegLiveness() const { return false; }
    304 
    305   /// This is called after a .mir file was loaded.
    306   virtual void mirFileLoaded(MachineFunction &MF) const;
    307 
    308   /// True if the register allocator should use the allocation orders exactly as
    309   /// written in the tablegen descriptions, false if it should allocate
    310   /// the specified physical register later if is it callee-saved.
    311   virtual bool ignoreCSRForAllocationOrder(const MachineFunction &MF,
    312                                            unsigned PhysReg) const {
    313     return false;
    314   }
    315 };
    316 
    317 } // end namespace llvm
    318 
    319 #endif // LLVM_CODEGEN_TARGETSUBTARGETINFO_H
    320