[InstCombine] Signed saturation patterns
[llvm-core.git] / include / llvm / MC / MCSubtargetInfo.h
blob09130c4641ef18c7e1670a72a54ab94919ea2b4a
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 //===----------------------------------------------------------------------===//
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
40 /// Compare routine for std::lower_bound
41 bool operator<(StringRef S) const {
42 return StringRef(Key) < S;
45 /// Compare routine for std::is_sorted.
46 bool operator<(const SubtargetFeatureKV &Other) const {
47 return StringRef(Key) < StringRef(Other.Key);
51 //===----------------------------------------------------------------------===//
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 const MCSchedModel *SchedModel;
59 /// Compare routine for std::lower_bound
60 bool operator<(StringRef S) const {
61 return StringRef(Key) < S;
64 /// Compare routine for std::is_sorted.
65 bool operator<(const SubtargetSubTypeKV &Other) const {
66 return StringRef(Key) < StringRef(Other.Key);
70 //===----------------------------------------------------------------------===//
71 ///
72 /// Generic base class for all target subtargets.
73 ///
74 class MCSubtargetInfo {
75 Triple TargetTriple;
76 std::string CPU; // CPU being targeted.
77 ArrayRef<SubtargetFeatureKV> ProcFeatures; // Processor feature list
78 ArrayRef<SubtargetSubTypeKV> ProcDesc; // Processor descriptions
80 // Scheduler machine model
81 const MCWriteProcResEntry *WriteProcResTable;
82 const MCWriteLatencyEntry *WriteLatencyTable;
83 const MCReadAdvanceEntry *ReadAdvanceTable;
84 const MCSchedModel *CPUSchedModel;
86 const InstrStage *Stages; // Instruction itinerary stages
87 const unsigned *OperandCycles; // Itinerary operand cycles
88 const unsigned *ForwardingPaths;
89 FeatureBitset FeatureBits; // Feature bits for current CPU + FS
91 public:
92 MCSubtargetInfo(const MCSubtargetInfo &) = default;
93 MCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS,
94 ArrayRef<SubtargetFeatureKV> PF,
95 ArrayRef<SubtargetSubTypeKV> PD,
96 const MCWriteProcResEntry *WPR, const MCWriteLatencyEntry *WL,
97 const MCReadAdvanceEntry *RA, const InstrStage *IS,
98 const unsigned *OC, const unsigned *FP);
99 MCSubtargetInfo() = delete;
100 MCSubtargetInfo &operator=(const MCSubtargetInfo &) = delete;
101 MCSubtargetInfo &operator=(MCSubtargetInfo &&) = delete;
102 virtual ~MCSubtargetInfo() = default;
104 const Triple &getTargetTriple() const { return TargetTriple; }
105 StringRef getCPU() const { return CPU; }
107 const FeatureBitset& getFeatureBits() const { return FeatureBits; }
108 void setFeatureBits(const FeatureBitset &FeatureBits_) {
109 FeatureBits = FeatureBits_;
112 bool hasFeature(unsigned Feature) const {
113 return FeatureBits[Feature];
116 protected:
117 /// Initialize the scheduling model and feature bits.
119 /// FIXME: Find a way to stick this in the constructor, since it should only
120 /// be called during initialization.
121 void InitMCProcessorInfo(StringRef CPU, StringRef FS);
123 public:
124 /// Set the features to the default for the given CPU with an appended feature
125 /// string.
126 void setDefaultFeatures(StringRef CPU, StringRef FS);
128 /// Toggle a feature and return the re-computed feature bits.
129 /// This version does not change the implied bits.
130 FeatureBitset ToggleFeature(uint64_t FB);
132 /// Toggle a feature and return the re-computed feature bits.
133 /// This version does not change the implied bits.
134 FeatureBitset ToggleFeature(const FeatureBitset& FB);
136 /// Toggle a set of features and return the re-computed feature bits.
137 /// This version will also change all implied bits.
138 FeatureBitset ToggleFeature(StringRef FS);
140 /// Apply a feature flag and return the re-computed feature bits, including
141 /// all feature bits implied by the flag.
142 FeatureBitset ApplyFeatureFlag(StringRef FS);
144 /// Set/clear additional feature bits, including all other bits they imply.
145 FeatureBitset SetFeatureBitsTransitively(const FeatureBitset& FB);
146 FeatureBitset ClearFeatureBitsTransitively(const FeatureBitset &FB);
148 /// Check whether the subtarget features are enabled/disabled as per
149 /// the provided string, ignoring all other features.
150 bool checkFeatures(StringRef FS) const;
152 /// Get the machine model of a CPU.
153 const MCSchedModel &getSchedModelForCPU(StringRef CPU) const;
155 /// Get the machine model for this subtarget's CPU.
156 const MCSchedModel &getSchedModel() const { return *CPUSchedModel; }
158 /// Return an iterator at the first process resource consumed by the given
159 /// scheduling class.
160 const MCWriteProcResEntry *getWriteProcResBegin(
161 const MCSchedClassDesc *SC) const {
162 return &WriteProcResTable[SC->WriteProcResIdx];
164 const MCWriteProcResEntry *getWriteProcResEnd(
165 const MCSchedClassDesc *SC) const {
166 return getWriteProcResBegin(SC) + SC->NumWriteProcResEntries;
169 const MCWriteLatencyEntry *getWriteLatencyEntry(const MCSchedClassDesc *SC,
170 unsigned DefIdx) const {
171 assert(DefIdx < SC->NumWriteLatencyEntries &&
172 "MachineModel does not specify a WriteResource for DefIdx");
174 return &WriteLatencyTable[SC->WriteLatencyIdx + DefIdx];
177 int getReadAdvanceCycles(const MCSchedClassDesc *SC, unsigned UseIdx,
178 unsigned WriteResID) const {
179 // TODO: The number of read advance entries in a class can be significant
180 // (~50). Consider compressing the WriteID into a dense ID of those that are
181 // used by ReadAdvance and representing them as a bitset.
182 for (const MCReadAdvanceEntry *I = &ReadAdvanceTable[SC->ReadAdvanceIdx],
183 *E = I + SC->NumReadAdvanceEntries; I != E; ++I) {
184 if (I->UseIdx < UseIdx)
185 continue;
186 if (I->UseIdx > UseIdx)
187 break;
188 // Find the first WriteResIdx match, which has the highest cycle count.
189 if (!I->WriteResourceID || I->WriteResourceID == WriteResID) {
190 return I->Cycles;
193 return 0;
196 /// Return the set of ReadAdvance entries declared by the scheduling class
197 /// descriptor in input.
198 ArrayRef<MCReadAdvanceEntry>
199 getReadAdvanceEntries(const MCSchedClassDesc &SC) const {
200 if (!SC.NumReadAdvanceEntries)
201 return ArrayRef<MCReadAdvanceEntry>();
202 return ArrayRef<MCReadAdvanceEntry>(&ReadAdvanceTable[SC.ReadAdvanceIdx],
203 SC.NumReadAdvanceEntries);
206 /// Get scheduling itinerary of a CPU.
207 InstrItineraryData getInstrItineraryForCPU(StringRef CPU) const;
209 /// Initialize an InstrItineraryData instance.
210 void initInstrItins(InstrItineraryData &InstrItins) const;
212 /// Resolve a variant scheduling class for the given MCInst and CPU.
213 virtual unsigned
214 resolveVariantSchedClass(unsigned SchedClass, const MCInst *MI,
215 unsigned CPUID) const {
216 return 0;
219 /// Check whether the CPU string is valid.
220 bool isCPUStringValid(StringRef CPU) const {
221 auto Found = std::lower_bound(ProcDesc.begin(), ProcDesc.end(), CPU);
222 return Found != ProcDesc.end() && StringRef(Found->Key) == CPU;
225 virtual unsigned getHwMode() const { return 0; }
227 /// Return the cache size in bytes for the given level of cache.
228 /// Level is zero-based, so a value of zero means the first level of
229 /// cache.
231 virtual Optional<unsigned> getCacheSize(unsigned Level) const;
233 /// Return the cache associatvity for the given level of cache.
234 /// Level is zero-based, so a value of zero means the first level of
235 /// cache.
237 virtual Optional<unsigned> getCacheAssociativity(unsigned Level) const;
239 /// Return the target cache line size in bytes at a given level.
241 virtual Optional<unsigned> getCacheLineSize(unsigned Level) const;
243 /// Return the target cache line size in bytes. By default, return
244 /// the line size for the bottom-most level of cache. This provides
245 /// a more convenient interface for the common case where all cache
246 /// levels have the same line size. Return zero if there is no
247 /// cache model.
249 virtual unsigned getCacheLineSize() const {
250 Optional<unsigned> Size = getCacheLineSize(0);
251 if (Size)
252 return *Size;
254 return 0;
257 /// Return the preferred prefetch distance in terms of instructions.
259 virtual unsigned getPrefetchDistance() const;
261 /// Return the maximum prefetch distance in terms of loop
262 /// iterations.
264 virtual unsigned getMaxPrefetchIterationsAhead() const;
266 /// Return the minimum stride necessary to trigger software
267 /// prefetching.
269 virtual unsigned getMinPrefetchStride() const;
272 } // end namespace llvm
274 #endif // LLVM_MC_MCSUBTARGETINFO_H