Home | History | Annotate | Download | only in MC
      1 //==-- llvm/MC/MCSubtargetInfo.h - Subtarget Information ---------*- C++ -*-==//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file describes the subtarget options of a Target machine.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #ifndef LLVM_MC_MCSUBTARGETINFO_H
     15 #define LLVM_MC_MCSUBTARGETINFO_H
     16 
     17 #include "llvm/MC/MCInstrItineraries.h"
     18 #include "llvm/MC/SubtargetFeature.h"
     19 #include <string>
     20 
     21 namespace llvm {
     22 
     23 class StringRef;
     24 
     25 //===----------------------------------------------------------------------===//
     26 ///
     27 /// MCSubtargetInfo - Generic base class for all target subtargets.
     28 ///
     29 class MCSubtargetInfo {
     30   Triple TargetTriple;                        // Target triple
     31   std::string CPU; // CPU being targeted.
     32   ArrayRef<SubtargetFeatureKV> ProcFeatures;  // Processor feature list
     33   ArrayRef<SubtargetFeatureKV> ProcDesc;  // Processor descriptions
     34 
     35   // Scheduler machine model
     36   const SubtargetInfoKV *ProcSchedModels;
     37   const MCWriteProcResEntry *WriteProcResTable;
     38   const MCWriteLatencyEntry *WriteLatencyTable;
     39   const MCReadAdvanceEntry *ReadAdvanceTable;
     40   const MCSchedModel *CPUSchedModel;
     41 
     42   const InstrStage *Stages;            // Instruction itinerary stages
     43   const unsigned *OperandCycles;       // Itinerary operand cycles
     44   const unsigned *ForwardingPaths;     // Forwarding paths
     45   FeatureBitset FeatureBits;           // Feature bits for current CPU + FS
     46 
     47   MCSubtargetInfo() = delete;
     48   MCSubtargetInfo &operator=(MCSubtargetInfo &&) = delete;
     49   MCSubtargetInfo &operator=(const MCSubtargetInfo &) = delete;
     50 
     51 public:
     52   MCSubtargetInfo(const MCSubtargetInfo &) = default;
     53   MCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS,
     54                   ArrayRef<SubtargetFeatureKV> PF,
     55                   ArrayRef<SubtargetFeatureKV> PD,
     56                   const SubtargetInfoKV *ProcSched,
     57                   const MCWriteProcResEntry *WPR, const MCWriteLatencyEntry *WL,
     58                   const MCReadAdvanceEntry *RA, const InstrStage *IS,
     59                   const unsigned *OC, const unsigned *FP);
     60 
     61   /// getTargetTriple - Return the target triple string.
     62   const Triple &getTargetTriple() const { return TargetTriple; }
     63 
     64   /// getCPU - Return the CPU string.
     65   StringRef getCPU() const {
     66     return CPU;
     67   }
     68 
     69   /// getFeatureBits - Return the feature bits.
     70   ///
     71   const FeatureBitset& getFeatureBits() const {
     72     return FeatureBits;
     73   }
     74 
     75   /// setFeatureBits - Set the feature bits.
     76   ///
     77   void setFeatureBits(const FeatureBitset &FeatureBits_) {
     78     FeatureBits = FeatureBits_;
     79   }
     80 
     81 protected:
     82   /// Initialize the scheduling model and feature bits.
     83   ///
     84   /// FIXME: Find a way to stick this in the constructor, since it should only
     85   /// be called during initialization.
     86   void InitMCProcessorInfo(StringRef CPU, StringRef FS);
     87 
     88 public:
     89   /// Set the features to the default for the given CPU with an appended feature
     90   /// string.
     91   void setDefaultFeatures(StringRef CPU, StringRef FS);
     92 
     93   /// ToggleFeature - Toggle a feature and returns the re-computed feature
     94   /// bits. This version does not change the implied bits.
     95   FeatureBitset ToggleFeature(uint64_t FB);
     96 
     97   /// ToggleFeature - Toggle a feature and returns the re-computed feature
     98   /// bits. This version does not change the implied bits.
     99   FeatureBitset ToggleFeature(const FeatureBitset& FB);
    100 
    101   /// ToggleFeature - Toggle a set of features and returns the re-computed
    102   /// feature bits. This version will also change all implied bits.
    103   FeatureBitset ToggleFeature(StringRef FS);
    104 
    105   /// Apply a feature flag and return the re-computed feature bits, including
    106   /// all feature bits implied by the flag.
    107   FeatureBitset ApplyFeatureFlag(StringRef FS);
    108 
    109   /// getSchedModelForCPU - Get the machine model of a CPU.
    110   ///
    111   const MCSchedModel &getSchedModelForCPU(StringRef CPU) const;
    112 
    113   /// Get the machine model for this subtarget's CPU.
    114   const MCSchedModel &getSchedModel() const { return *CPUSchedModel; }
    115 
    116   /// Return an iterator at the first process resource consumed by the given
    117   /// scheduling class.
    118   const MCWriteProcResEntry *getWriteProcResBegin(
    119     const MCSchedClassDesc *SC) const {
    120     return &WriteProcResTable[SC->WriteProcResIdx];
    121   }
    122   const MCWriteProcResEntry *getWriteProcResEnd(
    123     const MCSchedClassDesc *SC) const {
    124     return getWriteProcResBegin(SC) + SC->NumWriteProcResEntries;
    125   }
    126 
    127   const MCWriteLatencyEntry *getWriteLatencyEntry(const MCSchedClassDesc *SC,
    128                                                   unsigned DefIdx) const {
    129     assert(DefIdx < SC->NumWriteLatencyEntries &&
    130            "MachineModel does not specify a WriteResource for DefIdx");
    131 
    132     return &WriteLatencyTable[SC->WriteLatencyIdx + DefIdx];
    133   }
    134 
    135   int getReadAdvanceCycles(const MCSchedClassDesc *SC, unsigned UseIdx,
    136                            unsigned WriteResID) const {
    137     // TODO: The number of read advance entries in a class can be significant
    138     // (~50). Consider compressing the WriteID into a dense ID of those that are
    139     // used by ReadAdvance and representing them as a bitset.
    140     for (const MCReadAdvanceEntry *I = &ReadAdvanceTable[SC->ReadAdvanceIdx],
    141            *E = I + SC->NumReadAdvanceEntries; I != E; ++I) {
    142       if (I->UseIdx < UseIdx)
    143         continue;
    144       if (I->UseIdx > UseIdx)
    145         break;
    146       // Find the first WriteResIdx match, which has the highest cycle count.
    147       if (!I->WriteResourceID || I->WriteResourceID == WriteResID) {
    148         return I->Cycles;
    149       }
    150     }
    151     return 0;
    152   }
    153 
    154   /// getInstrItineraryForCPU - Get scheduling itinerary of a CPU.
    155   ///
    156   InstrItineraryData getInstrItineraryForCPU(StringRef CPU) const;
    157 
    158   /// Initialize an InstrItineraryData instance.
    159   void initInstrItins(InstrItineraryData &InstrItins) const;
    160 
    161   /// Check whether the CPU string is valid.
    162   bool isCPUStringValid(StringRef CPU) const {
    163     auto Found = std::lower_bound(ProcDesc.begin(), ProcDesc.end(), CPU);
    164     return Found != ProcDesc.end() && StringRef(Found->Key) == CPU;
    165   }
    166 };
    167 
    168 } // End llvm namespace
    169 
    170 #endif
    171