Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:44:15

0001 //===- llvm/MC/MCSubtargetInfo.h - Subtarget Information --------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file describes the subtarget options of a Target machine.
0010 //
0011 //===----------------------------------------------------------------------===//
0012 
0013 #ifndef LLVM_MC_MCSUBTARGETINFO_H
0014 #define LLVM_MC_MCSUBTARGETINFO_H
0015 
0016 #include "llvm/ADT/ArrayRef.h"
0017 #include "llvm/ADT/STLExtras.h"
0018 #include "llvm/ADT/StringRef.h"
0019 #include "llvm/MC/MCInstrItineraries.h"
0020 #include "llvm/MC/MCSchedule.h"
0021 #include "llvm/TargetParser/SubtargetFeature.h"
0022 #include "llvm/TargetParser/Triple.h"
0023 #include <cassert>
0024 #include <cstdint>
0025 #include <optional>
0026 #include <string>
0027 
0028 namespace llvm {
0029 
0030 class MCInst;
0031 
0032 //===----------------------------------------------------------------------===//
0033 
0034 /// Used to provide key value pairs for feature and CPU bit flags.
0035 struct SubtargetFeatureKV {
0036   const char *Key;                      ///< K-V key string
0037   const char *Desc;                     ///< Help descriptor
0038   unsigned Value;                       ///< K-V integer value
0039   FeatureBitArray Implies;              ///< K-V bit mask
0040 
0041   /// Compare routine for std::lower_bound
0042   bool operator<(StringRef S) const {
0043     return StringRef(Key) < S;
0044   }
0045 
0046   /// Compare routine for std::is_sorted.
0047   bool operator<(const SubtargetFeatureKV &Other) const {
0048     return StringRef(Key) < StringRef(Other.Key);
0049   }
0050 };
0051 
0052 //===----------------------------------------------------------------------===//
0053 
0054 /// Used to provide key value pairs for feature and CPU bit flags.
0055 struct SubtargetSubTypeKV {
0056   const char *Key;                      ///< K-V key string
0057   FeatureBitArray Implies;              ///< K-V bit mask
0058   FeatureBitArray TuneImplies;          ///< K-V bit mask
0059   const MCSchedModel *SchedModel;
0060 
0061   /// Compare routine for std::lower_bound
0062   bool operator<(StringRef S) const {
0063     return StringRef(Key) < S;
0064   }
0065 
0066   /// Compare routine for std::is_sorted.
0067   bool operator<(const SubtargetSubTypeKV &Other) const {
0068     return StringRef(Key) < StringRef(Other.Key);
0069   }
0070 };
0071 
0072 //===----------------------------------------------------------------------===//
0073 ///
0074 /// Generic base class for all target subtargets.
0075 ///
0076 class MCSubtargetInfo {
0077   Triple TargetTriple;
0078   std::string CPU; // CPU being targeted.
0079   std::string TuneCPU; // CPU being tuned for.
0080   ArrayRef<StringRef> ProcNames; // Processor list, including aliases
0081   ArrayRef<SubtargetFeatureKV> ProcFeatures;  // Processor feature list
0082   ArrayRef<SubtargetSubTypeKV> ProcDesc;  // Processor descriptions
0083 
0084   // Scheduler machine model
0085   const MCWriteProcResEntry *WriteProcResTable;
0086   const MCWriteLatencyEntry *WriteLatencyTable;
0087   const MCReadAdvanceEntry *ReadAdvanceTable;
0088   const MCSchedModel *CPUSchedModel;
0089 
0090   const InstrStage *Stages;            // Instruction itinerary stages
0091   const unsigned *OperandCycles;       // Itinerary operand cycles
0092   const unsigned *ForwardingPaths;
0093   FeatureBitset FeatureBits;           // Feature bits for current CPU + FS
0094   std::string FeatureString;           // Feature string
0095 
0096 public:
0097   MCSubtargetInfo(const MCSubtargetInfo &) = default;
0098   MCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef TuneCPU,
0099                   StringRef FS, ArrayRef<StringRef> PN,
0100                   ArrayRef<SubtargetFeatureKV> PF,
0101                   ArrayRef<SubtargetSubTypeKV> PD,
0102                   const MCWriteProcResEntry *WPR, const MCWriteLatencyEntry *WL,
0103                   const MCReadAdvanceEntry *RA, const InstrStage *IS,
0104                   const unsigned *OC, const unsigned *FP);
0105   MCSubtargetInfo() = delete;
0106   MCSubtargetInfo &operator=(const MCSubtargetInfo &) = delete;
0107   MCSubtargetInfo &operator=(MCSubtargetInfo &&) = delete;
0108   virtual ~MCSubtargetInfo() = default;
0109 
0110   const Triple &getTargetTriple() const { return TargetTriple; }
0111   StringRef getCPU() const { return CPU; }
0112   StringRef getTuneCPU() const { return TuneCPU; }
0113 
0114   const FeatureBitset& getFeatureBits() const { return FeatureBits; }
0115   void setFeatureBits(const FeatureBitset &FeatureBits_) {
0116     FeatureBits = FeatureBits_;
0117   }
0118 
0119   StringRef getFeatureString() const { return FeatureString; }
0120 
0121   bool hasFeature(unsigned Feature) const {
0122     return FeatureBits[Feature];
0123   }
0124 
0125 protected:
0126   /// Initialize the scheduling model and feature bits.
0127   ///
0128   /// FIXME: Find a way to stick this in the constructor, since it should only
0129   /// be called during initialization.
0130   void InitMCProcessorInfo(StringRef CPU, StringRef TuneCPU, StringRef FS);
0131 
0132 public:
0133   /// Set the features to the default for the given CPU and TuneCPU, with ano
0134   /// appended feature string.
0135   void setDefaultFeatures(StringRef CPU, StringRef TuneCPU, StringRef FS);
0136 
0137   /// Toggle a feature and return the re-computed feature bits.
0138   /// This version does not change the implied bits.
0139   FeatureBitset ToggleFeature(uint64_t FB);
0140 
0141   /// Toggle a feature and return the re-computed feature bits.
0142   /// This version does not change the implied bits.
0143   FeatureBitset ToggleFeature(const FeatureBitset& FB);
0144 
0145   /// Toggle a set of features and return the re-computed feature bits.
0146   /// This version will also change all implied bits.
0147   FeatureBitset ToggleFeature(StringRef FS);
0148 
0149   /// Apply a feature flag and return the re-computed feature bits, including
0150   /// all feature bits implied by the flag.
0151   FeatureBitset ApplyFeatureFlag(StringRef FS);
0152 
0153   /// Set/clear additional feature bits, including all other bits they imply.
0154   FeatureBitset SetFeatureBitsTransitively(const FeatureBitset& FB);
0155   FeatureBitset ClearFeatureBitsTransitively(const FeatureBitset &FB);
0156 
0157   /// Check whether the subtarget features are enabled/disabled as per
0158   /// the provided string, ignoring all other features.
0159   bool checkFeatures(StringRef FS) const;
0160 
0161   /// Get the machine model of a CPU.
0162   const MCSchedModel &getSchedModelForCPU(StringRef CPU) const;
0163 
0164   /// Get the machine model for this subtarget's CPU.
0165   const MCSchedModel &getSchedModel() const { return *CPUSchedModel; }
0166 
0167   /// Return an iterator at the first process resource consumed by the given
0168   /// scheduling class.
0169   const MCWriteProcResEntry *getWriteProcResBegin(
0170     const MCSchedClassDesc *SC) const {
0171     return &WriteProcResTable[SC->WriteProcResIdx];
0172   }
0173   const MCWriteProcResEntry *getWriteProcResEnd(
0174     const MCSchedClassDesc *SC) const {
0175     return getWriteProcResBegin(SC) + SC->NumWriteProcResEntries;
0176   }
0177 
0178   const MCWriteLatencyEntry *getWriteLatencyEntry(const MCSchedClassDesc *SC,
0179                                                   unsigned DefIdx) const {
0180     assert(DefIdx < SC->NumWriteLatencyEntries &&
0181            "MachineModel does not specify a WriteResource for DefIdx");
0182 
0183     return &WriteLatencyTable[SC->WriteLatencyIdx + DefIdx];
0184   }
0185 
0186   int getReadAdvanceCycles(const MCSchedClassDesc *SC, unsigned UseIdx,
0187                            unsigned WriteResID) const {
0188     // TODO: The number of read advance entries in a class can be significant
0189     // (~50). Consider compressing the WriteID into a dense ID of those that are
0190     // used by ReadAdvance and representing them as a bitset.
0191     for (const MCReadAdvanceEntry *I = &ReadAdvanceTable[SC->ReadAdvanceIdx],
0192            *E = I + SC->NumReadAdvanceEntries; I != E; ++I) {
0193       if (I->UseIdx < UseIdx)
0194         continue;
0195       if (I->UseIdx > UseIdx)
0196         break;
0197       // Find the first WriteResIdx match, which has the highest cycle count.
0198       if (!I->WriteResourceID || I->WriteResourceID == WriteResID) {
0199         return I->Cycles;
0200       }
0201     }
0202     return 0;
0203   }
0204 
0205   /// Return the set of ReadAdvance entries declared by the scheduling class
0206   /// descriptor in input.
0207   ArrayRef<MCReadAdvanceEntry>
0208   getReadAdvanceEntries(const MCSchedClassDesc &SC) const {
0209     if (!SC.NumReadAdvanceEntries)
0210       return ArrayRef<MCReadAdvanceEntry>();
0211     return ArrayRef<MCReadAdvanceEntry>(&ReadAdvanceTable[SC.ReadAdvanceIdx],
0212                                         SC.NumReadAdvanceEntries);
0213   }
0214 
0215   /// Get scheduling itinerary of a CPU.
0216   InstrItineraryData getInstrItineraryForCPU(StringRef CPU) const;
0217 
0218   /// Initialize an InstrItineraryData instance.
0219   void initInstrItins(InstrItineraryData &InstrItins) const;
0220 
0221   /// Resolve a variant scheduling class for the given MCInst and CPU.
0222   virtual unsigned resolveVariantSchedClass(unsigned SchedClass,
0223                                             const MCInst *MI,
0224                                             const MCInstrInfo *MCII,
0225                                             unsigned CPUID) const {
0226     return 0;
0227   }
0228 
0229   /// Check whether the CPU string is valid.
0230   virtual bool isCPUStringValid(StringRef CPU) const {
0231     auto Found = llvm::lower_bound(ProcDesc, CPU);
0232     return Found != ProcDesc.end() && StringRef(Found->Key) == CPU;
0233   }
0234 
0235   /// Return processor descriptions.
0236   ArrayRef<SubtargetSubTypeKV> getAllProcessorDescriptions() const {
0237     return ProcDesc;
0238   }
0239 
0240   /// Return processor features.
0241   ArrayRef<SubtargetFeatureKV> getAllProcessorFeatures() const {
0242     return ProcFeatures;
0243   }
0244 
0245   /// Return the list of processor features currently enabled.
0246   std::vector<SubtargetFeatureKV> getEnabledProcessorFeatures() const;
0247 
0248   /// HwMode IDs are stored and accessed in a bit set format, enabling
0249   /// users to efficiently retrieve specific IDs, such as the RegInfo
0250   /// HwMode ID, from the set as required. Using this approach, various
0251   /// types of HwMode IDs can be added to a subtarget to manage different
0252   /// attributes within that subtarget, significantly enhancing the
0253   /// scalability and usability of HwMode. Moreover, to ensure compatibility,
0254   /// this method also supports controlling multiple attributes with a single
0255   /// HwMode ID, just as was done previously.
0256   enum HwModeType {
0257     HwMode_Default,   // Return the smallest HwMode ID of current subtarget.
0258     HwMode_ValueType, // Return the HwMode ID that controls the ValueType.
0259     HwMode_RegInfo,   // Return the HwMode ID that controls the RegSizeInfo and
0260                       // SubRegRange.
0261     HwMode_EncodingInfo // Return the HwMode ID that controls the EncodingInfo.
0262   };
0263 
0264   /// Return a bit set containing all HwMode IDs of the current subtarget.
0265   virtual unsigned getHwModeSet() const { return 0; }
0266 
0267   /// HwMode ID corresponding to the 'type' parameter is retrieved from the
0268   /// HwMode bit set of the current subtarget. It’s important to note that if
0269   /// the current subtarget possesses two HwMode IDs and both control a single
0270   /// attribute (such as RegInfo), this interface will result in an error.
0271   virtual unsigned getHwMode(enum HwModeType type = HwMode_Default) const {
0272     return 0;
0273   }
0274 
0275   /// Return the cache size in bytes for the given level of cache.
0276   /// Level is zero-based, so a value of zero means the first level of
0277   /// cache.
0278   ///
0279   virtual std::optional<unsigned> getCacheSize(unsigned Level) const;
0280 
0281   /// Return the cache associatvity for the given level of cache.
0282   /// Level is zero-based, so a value of zero means the first level of
0283   /// cache.
0284   ///
0285   virtual std::optional<unsigned> getCacheAssociativity(unsigned Level) const;
0286 
0287   /// Return the target cache line size in bytes at a given level.
0288   ///
0289   virtual std::optional<unsigned> getCacheLineSize(unsigned Level) const;
0290 
0291   /// Return the target cache line size in bytes.  By default, return
0292   /// the line size for the bottom-most level of cache.  This provides
0293   /// a more convenient interface for the common case where all cache
0294   /// levels have the same line size.  Return zero if there is no
0295   /// cache model.
0296   ///
0297   virtual unsigned getCacheLineSize() const {
0298     std::optional<unsigned> Size = getCacheLineSize(0);
0299     if (Size)
0300       return *Size;
0301 
0302     return 0;
0303   }
0304 
0305   /// Return the preferred prefetch distance in terms of instructions.
0306   ///
0307   virtual unsigned getPrefetchDistance() const;
0308 
0309   /// Return the maximum prefetch distance in terms of loop
0310   /// iterations.
0311   ///
0312   virtual unsigned getMaxPrefetchIterationsAhead() const;
0313 
0314   /// \return True if prefetching should also be done for writes.
0315   ///
0316   virtual bool enableWritePrefetching() const;
0317 
0318   /// Return the minimum stride necessary to trigger software
0319   /// prefetching.
0320   ///
0321   virtual unsigned getMinPrefetchStride(unsigned NumMemAccesses,
0322                                         unsigned NumStridedMemAccesses,
0323                                         unsigned NumPrefetches,
0324                                         bool HasCall) const;
0325 
0326   /// \return if target want to issue a prefetch in address space \p AS.
0327   virtual bool shouldPrefetchAddressSpace(unsigned AS) const;
0328 };
0329 
0330 } // end namespace llvm
0331 
0332 #endif // LLVM_MC_MCSUBTARGETINFO_H