Home | History | Annotate | Line # | Download | only in MC
      1 //===- llvm/MC/MCSubtargetInfo.h - Subtarget 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_MC_MCSUBTARGETINFO_H
     14 #define LLVM_MC_MCSUBTARGETINFO_H
     15 
     16 #include "llvm/ADT/ArrayRef.h"
     17 #include "llvm/ADT/StringRef.h"
     18 #include "llvm/ADT/Triple.h"
     19 #include "llvm/MC/MCInstrItineraries.h"
     20 #include "llvm/MC/MCSchedule.h"
     21 #include "llvm/MC/SubtargetFeature.h"
     22 #include <algorithm>
     23 #include <cassert>
     24 #include <cstdint>
     25 #include <string>
     26 
     27 namespace llvm {
     28 
     29 class MCInst;
     30 
     31 //===----------------------------------------------------------------------===//
     32 
     33 /// Used to provide key value pairs for feature and CPU bit flags.
     34 struct SubtargetFeatureKV {
     35   const char *Key;                      ///< K-V key string
     36   const char *Desc;                     ///< Help descriptor
     37   unsigned Value;                       ///< K-V integer value
     38   FeatureBitArray Implies;              ///< K-V bit mask
     39 
     40   /// Compare routine for std::lower_bound
     41   bool operator<(StringRef S) const {
     42     return StringRef(Key) < S;
     43   }
     44 
     45   /// Compare routine for std::is_sorted.
     46   bool operator<(const SubtargetFeatureKV &Other) const {
     47     return StringRef(Key) < StringRef(Other.Key);
     48   }
     49 };
     50 
     51 //===----------------------------------------------------------------------===//
     52 
     53 /// Used to provide key value pairs for feature and CPU bit flags.
     54 struct SubtargetSubTypeKV {
     55   const char *Key;                      ///< K-V key string
     56   FeatureBitArray Implies;              ///< K-V bit mask
     57   FeatureBitArray TuneImplies;          ///< K-V bit mask
     58   const MCSchedModel *SchedModel;
     59 
     60   /// Compare routine for std::lower_bound
     61   bool operator<(StringRef S) const {
     62     return StringRef(Key) < S;
     63   }
     64 
     65   /// Compare routine for std::is_sorted.
     66   bool operator<(const SubtargetSubTypeKV &Other) const {
     67     return StringRef(Key) < StringRef(Other.Key);
     68   }
     69 };
     70 
     71 //===----------------------------------------------------------------------===//
     72 ///
     73 /// Generic base class for all target subtargets.
     74 ///
     75 class MCSubtargetInfo {
     76   Triple TargetTriple;
     77   std::string CPU; // CPU being targeted.
     78   std::string TuneCPU; // CPU being tuned for.
     79   ArrayRef<SubtargetFeatureKV> ProcFeatures;  // Processor feature list
     80   ArrayRef<SubtargetSubTypeKV> ProcDesc;  // Processor descriptions
     81 
     82   // Scheduler machine model
     83   const MCWriteProcResEntry *WriteProcResTable;
     84   const MCWriteLatencyEntry *WriteLatencyTable;
     85   const MCReadAdvanceEntry *ReadAdvanceTable;
     86   const MCSchedModel *CPUSchedModel;
     87 
     88   const InstrStage *Stages;            // Instruction itinerary stages
     89   const unsigned *OperandCycles;       // Itinerary operand cycles
     90   const unsigned *ForwardingPaths;
     91   FeatureBitset FeatureBits;           // Feature bits for current CPU + FS
     92   std::string FeatureString;           // Feature string
     93 
     94 public:
     95   MCSubtargetInfo(const MCSubtargetInfo &) = default;
     96   MCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef TuneCPU,
     97                   StringRef FS, ArrayRef<SubtargetFeatureKV> PF,
     98                   ArrayRef<SubtargetSubTypeKV> PD,
     99                   const MCWriteProcResEntry *WPR, const MCWriteLatencyEntry *WL,
    100                   const MCReadAdvanceEntry *RA, const InstrStage *IS,
    101                   const unsigned *OC, const unsigned *FP);
    102   MCSubtargetInfo() = delete;
    103   MCSubtargetInfo &operator=(const MCSubtargetInfo &) = delete;
    104   MCSubtargetInfo &operator=(MCSubtargetInfo &&) = delete;
    105   virtual ~MCSubtargetInfo() = default;
    106 
    107   const Triple &getTargetTriple() const { return TargetTriple; }
    108   StringRef getCPU() const { return CPU; }
    109   StringRef getTuneCPU() const { return TuneCPU; }
    110 
    111   const FeatureBitset& getFeatureBits() const { return FeatureBits; }
    112   void setFeatureBits(const FeatureBitset &FeatureBits_) {
    113     FeatureBits = FeatureBits_;
    114   }
    115 
    116   StringRef getFeatureString() const { return FeatureString; }
    117 
    118   bool hasFeature(unsigned Feature) const {
    119     return FeatureBits[Feature];
    120   }
    121 
    122 protected:
    123   /// Initialize the scheduling model and feature bits.
    124   ///
    125   /// FIXME: Find a way to stick this in the constructor, since it should only
    126   /// be called during initialization.
    127   void InitMCProcessorInfo(StringRef CPU, StringRef TuneCPU, StringRef FS);
    128 
    129 public:
    130   /// Set the features to the default for the given CPU and TuneCPU, with ano
    131   /// appended feature string.
    132   void setDefaultFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
    133 
    134   /// Toggle a feature and return the re-computed feature bits.
    135   /// This version does not change the implied bits.
    136   FeatureBitset ToggleFeature(uint64_t FB);
    137 
    138   /// Toggle a feature and return the re-computed feature bits.
    139   /// This version does not change the implied bits.
    140   FeatureBitset ToggleFeature(const FeatureBitset& FB);
    141 
    142   /// Toggle a set of features and return the re-computed feature bits.
    143   /// This version will also change all implied bits.
    144   FeatureBitset ToggleFeature(StringRef FS);
    145 
    146   /// Apply a feature flag and return the re-computed feature bits, including
    147   /// all feature bits implied by the flag.
    148   FeatureBitset ApplyFeatureFlag(StringRef FS);
    149 
    150   /// Set/clear additional feature bits, including all other bits they imply.
    151   FeatureBitset SetFeatureBitsTransitively(const FeatureBitset& FB);
    152   FeatureBitset ClearFeatureBitsTransitively(const FeatureBitset &FB);
    153 
    154   /// Check whether the subtarget features are enabled/disabled as per
    155   /// the provided string, ignoring all other features.
    156   bool checkFeatures(StringRef FS) const;
    157 
    158   /// Get the machine model of a CPU.
    159   const MCSchedModel &getSchedModelForCPU(StringRef CPU) const;
    160 
    161   /// Get the machine model for this subtarget's CPU.
    162   const MCSchedModel &getSchedModel() const { return *CPUSchedModel; }
    163 
    164   /// Return an iterator at the first process resource consumed by the given
    165   /// scheduling class.
    166   const MCWriteProcResEntry *getWriteProcResBegin(
    167     const MCSchedClassDesc *SC) const {
    168     return &WriteProcResTable[SC->WriteProcResIdx];
    169   }
    170   const MCWriteProcResEntry *getWriteProcResEnd(
    171     const MCSchedClassDesc *SC) const {
    172     return getWriteProcResBegin(SC) + SC->NumWriteProcResEntries;
    173   }
    174 
    175   const MCWriteLatencyEntry *getWriteLatencyEntry(const MCSchedClassDesc *SC,
    176                                                   unsigned DefIdx) const {
    177     assert(DefIdx < SC->NumWriteLatencyEntries &&
    178            "MachineModel does not specify a WriteResource for DefIdx");
    179 
    180     return &WriteLatencyTable[SC->WriteLatencyIdx + DefIdx];
    181   }
    182 
    183   int getReadAdvanceCycles(const MCSchedClassDesc *SC, unsigned UseIdx,
    184                            unsigned WriteResID) const {
    185     // TODO: The number of read advance entries in a class can be significant
    186     // (~50). Consider compressing the WriteID into a dense ID of those that are
    187     // used by ReadAdvance and representing them as a bitset.
    188     for (const MCReadAdvanceEntry *I = &ReadAdvanceTable[SC->ReadAdvanceIdx],
    189            *E = I + SC->NumReadAdvanceEntries; I != E; ++I) {
    190       if (I->UseIdx < UseIdx)
    191         continue;
    192       if (I->UseIdx > UseIdx)
    193         break;
    194       // Find the first WriteResIdx match, which has the highest cycle count.
    195       if (!I->WriteResourceID || I->WriteResourceID == WriteResID) {
    196         return I->Cycles;
    197       }
    198     }
    199     return 0;
    200   }
    201 
    202   /// Return the set of ReadAdvance entries declared by the scheduling class
    203   /// descriptor in input.
    204   ArrayRef<MCReadAdvanceEntry>
    205   getReadAdvanceEntries(const MCSchedClassDesc &SC) const {
    206     if (!SC.NumReadAdvanceEntries)
    207       return ArrayRef<MCReadAdvanceEntry>();
    208     return ArrayRef<MCReadAdvanceEntry>(&ReadAdvanceTable[SC.ReadAdvanceIdx],
    209                                         SC.NumReadAdvanceEntries);
    210   }
    211 
    212   /// Get scheduling itinerary of a CPU.
    213   InstrItineraryData getInstrItineraryForCPU(StringRef CPU) const;
    214 
    215   /// Initialize an InstrItineraryData instance.
    216   void initInstrItins(InstrItineraryData &InstrItins) const;
    217 
    218   /// Resolve a variant scheduling class for the given MCInst and CPU.
    219   virtual unsigned resolveVariantSchedClass(unsigned SchedClass,
    220                                             const MCInst *MI,
    221                                             const MCInstrInfo *MCII,
    222                                             unsigned CPUID) const {
    223     return 0;
    224   }
    225 
    226   /// Check whether the CPU string is valid.
    227   bool isCPUStringValid(StringRef CPU) const {
    228     auto Found = llvm::lower_bound(ProcDesc, CPU);
    229     return Found != ProcDesc.end() && StringRef(Found->Key) == CPU;
    230   }
    231 
    232   virtual unsigned getHwMode() const { return 0; }
    233 
    234   /// Return the cache size in bytes for the given level of cache.
    235   /// Level is zero-based, so a value of zero means the first level of
    236   /// cache.
    237   ///
    238   virtual Optional<unsigned> getCacheSize(unsigned Level) const;
    239 
    240   /// Return the cache associatvity for the given level of cache.
    241   /// Level is zero-based, so a value of zero means the first level of
    242   /// cache.
    243   ///
    244   virtual Optional<unsigned> getCacheAssociativity(unsigned Level) const;
    245 
    246   /// Return the target cache line size in bytes at a given level.
    247   ///
    248   virtual Optional<unsigned> getCacheLineSize(unsigned Level) const;
    249 
    250   /// Return the target cache line size in bytes.  By default, return
    251   /// the line size for the bottom-most level of cache.  This provides
    252   /// a more convenient interface for the common case where all cache
    253   /// levels have the same line size.  Return zero if there is no
    254   /// cache model.
    255   ///
    256   virtual unsigned getCacheLineSize() const {
    257     Optional<unsigned> Size = getCacheLineSize(0);
    258     if (Size)
    259       return *Size;
    260 
    261     return 0;
    262   }
    263 
    264   /// Return the preferred prefetch distance in terms of instructions.
    265   ///
    266   virtual unsigned getPrefetchDistance() const;
    267 
    268   /// Return the maximum prefetch distance in terms of loop
    269   /// iterations.
    270   ///
    271   virtual unsigned getMaxPrefetchIterationsAhead() const;
    272 
    273   /// \return True if prefetching should also be done for writes.
    274   ///
    275   virtual bool enableWritePrefetching() const;
    276 
    277   /// Return the minimum stride necessary to trigger software
    278   /// prefetching.
    279   ///
    280   virtual unsigned getMinPrefetchStride(unsigned NumMemAccesses,
    281                                         unsigned NumStridedMemAccesses,
    282                                         unsigned NumPrefetches,
    283                                         bool HasCall) const;
    284 };
    285 
    286 } // end namespace llvm
    287 
    288 #endif // LLVM_MC_MCSUBTARGETINFO_H
    289