Recommit [NFC] Better encapsulation of llvm::Optional Storage
[llvm-complete.git] / include / llvm / MC / MCSubtargetInfo.h
blobc7472a28c7747329f758af1a96a24d29bf27959c
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.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_MC_MCSUBTARGETINFO_H
14 #define LLVM_MC_MCSUBTARGETINFO_H
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>
27 namespace llvm {
29 class MCInst;
31 //===----------------------------------------------------------------------===//
32 ///
33 /// Generic base class for all target subtargets.
34 ///
35 class MCSubtargetInfo {
36 Triple TargetTriple;
37 std::string CPU; // CPU being targeted.
38 ArrayRef<SubtargetFeatureKV> ProcFeatures; // Processor feature list
39 ArrayRef<SubtargetFeatureKV> ProcDesc; // Processor descriptions
41 // Scheduler machine model
42 const SubtargetInfoKV *ProcSchedModels;
43 const MCWriteProcResEntry *WriteProcResTable;
44 const MCWriteLatencyEntry *WriteLatencyTable;
45 const MCReadAdvanceEntry *ReadAdvanceTable;
46 const MCSchedModel *CPUSchedModel;
48 const InstrStage *Stages; // Instruction itinerary stages
49 const unsigned *OperandCycles; // Itinerary operand cycles
50 const unsigned *ForwardingPaths;
51 FeatureBitset FeatureBits; // Feature bits for current CPU + FS
53 public:
54 MCSubtargetInfo(const MCSubtargetInfo &) = default;
55 MCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS,
56 ArrayRef<SubtargetFeatureKV> PF,
57 ArrayRef<SubtargetFeatureKV> PD,
58 const SubtargetInfoKV *ProcSched,
59 const MCWriteProcResEntry *WPR, const MCWriteLatencyEntry *WL,
60 const MCReadAdvanceEntry *RA, const InstrStage *IS,
61 const unsigned *OC, const unsigned *FP);
62 MCSubtargetInfo() = delete;
63 MCSubtargetInfo &operator=(const MCSubtargetInfo &) = delete;
64 MCSubtargetInfo &operator=(MCSubtargetInfo &&) = delete;
65 virtual ~MCSubtargetInfo() = default;
67 const Triple &getTargetTriple() const { return TargetTriple; }
68 StringRef getCPU() const { return CPU; }
70 const FeatureBitset& getFeatureBits() const { return FeatureBits; }
71 void setFeatureBits(const FeatureBitset &FeatureBits_) {
72 FeatureBits = FeatureBits_;
75 bool hasFeature(unsigned Feature) const {
76 return FeatureBits[Feature];
79 protected:
80 /// Initialize the scheduling model and feature bits.
81 ///
82 /// FIXME: Find a way to stick this in the constructor, since it should only
83 /// be called during initialization.
84 void InitMCProcessorInfo(StringRef CPU, StringRef FS);
86 public:
87 /// Set the features to the default for the given CPU with an appended feature
88 /// string.
89 void setDefaultFeatures(StringRef CPU, StringRef FS);
91 /// Toggle a feature and return the re-computed feature bits.
92 /// This version does not change the implied bits.
93 FeatureBitset ToggleFeature(uint64_t FB);
95 /// Toggle a feature and return the re-computed feature bits.
96 /// This version does not change the implied bits.
97 FeatureBitset ToggleFeature(const FeatureBitset& FB);
99 /// Toggle a set of features and return the re-computed feature bits.
100 /// This version will also change all implied bits.
101 FeatureBitset ToggleFeature(StringRef FS);
103 /// Apply a feature flag and return the re-computed feature bits, including
104 /// all feature bits implied by the flag.
105 FeatureBitset ApplyFeatureFlag(StringRef FS);
107 /// Check whether the subtarget features are enabled/disabled as per
108 /// the provided string, ignoring all other features.
109 bool checkFeatures(StringRef FS) const;
111 /// Get the machine model of a CPU.
112 const MCSchedModel &getSchedModelForCPU(StringRef CPU) const;
114 /// Get the machine model for this subtarget's CPU.
115 const MCSchedModel &getSchedModel() const { return *CPUSchedModel; }
117 /// Return an iterator at the first process resource consumed by the given
118 /// scheduling class.
119 const MCWriteProcResEntry *getWriteProcResBegin(
120 const MCSchedClassDesc *SC) const {
121 return &WriteProcResTable[SC->WriteProcResIdx];
123 const MCWriteProcResEntry *getWriteProcResEnd(
124 const MCSchedClassDesc *SC) const {
125 return getWriteProcResBegin(SC) + SC->NumWriteProcResEntries;
128 const MCWriteLatencyEntry *getWriteLatencyEntry(const MCSchedClassDesc *SC,
129 unsigned DefIdx) const {
130 assert(DefIdx < SC->NumWriteLatencyEntries &&
131 "MachineModel does not specify a WriteResource for DefIdx");
133 return &WriteLatencyTable[SC->WriteLatencyIdx + DefIdx];
136 int getReadAdvanceCycles(const MCSchedClassDesc *SC, unsigned UseIdx,
137 unsigned WriteResID) const {
138 // TODO: The number of read advance entries in a class can be significant
139 // (~50). Consider compressing the WriteID into a dense ID of those that are
140 // used by ReadAdvance and representing them as a bitset.
141 for (const MCReadAdvanceEntry *I = &ReadAdvanceTable[SC->ReadAdvanceIdx],
142 *E = I + SC->NumReadAdvanceEntries; I != E; ++I) {
143 if (I->UseIdx < UseIdx)
144 continue;
145 if (I->UseIdx > UseIdx)
146 break;
147 // Find the first WriteResIdx match, which has the highest cycle count.
148 if (!I->WriteResourceID || I->WriteResourceID == WriteResID) {
149 return I->Cycles;
152 return 0;
155 /// Return the set of ReadAdvance entries declared by the scheduling class
156 /// descriptor in input.
157 ArrayRef<MCReadAdvanceEntry>
158 getReadAdvanceEntries(const MCSchedClassDesc &SC) const {
159 if (!SC.NumReadAdvanceEntries)
160 return ArrayRef<MCReadAdvanceEntry>();
161 return ArrayRef<MCReadAdvanceEntry>(&ReadAdvanceTable[SC.ReadAdvanceIdx],
162 SC.NumReadAdvanceEntries);
165 /// Get scheduling itinerary of a CPU.
166 InstrItineraryData getInstrItineraryForCPU(StringRef CPU) const;
168 /// Initialize an InstrItineraryData instance.
169 void initInstrItins(InstrItineraryData &InstrItins) const;
171 /// Resolve a variant scheduling class for the given MCInst and CPU.
172 virtual unsigned
173 resolveVariantSchedClass(unsigned SchedClass, const MCInst *MI,
174 unsigned CPUID) const {
175 return 0;
178 /// Check whether the CPU string is valid.
179 bool isCPUStringValid(StringRef CPU) const {
180 auto Found = std::lower_bound(ProcDesc.begin(), ProcDesc.end(), CPU);
181 return Found != ProcDesc.end() && StringRef(Found->Key) == CPU;
185 } // end namespace llvm
187 #endif // LLVM_MC_MCSUBTARGETINFO_H