1 //===- llvm/MC/MCSubtargetInfo.h - Subtarget Information --------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
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"
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 //===----------------------------------------------------------------------===//
72 /// Generic base class for all target subtargets.
74 class MCSubtargetInfo
{
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
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
];
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
);
124 /// Set the features to the default for the given CPU with an appended feature
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
)
186 if (I
->UseIdx
> UseIdx
)
188 // Find the first WriteResIdx match, which has the highest cycle count.
189 if (!I
->WriteResourceID
|| I
->WriteResourceID
== WriteResID
) {
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.
214 resolveVariantSchedClass(unsigned SchedClass
, const MCInst
*MI
,
215 unsigned CPUID
) const {
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
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
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
249 virtual unsigned getCacheLineSize() const {
250 Optional
<unsigned> Size
= getCacheLineSize(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
264 virtual unsigned getMaxPrefetchIterationsAhead() const;
266 /// Return the minimum stride necessary to trigger software
269 virtual unsigned getMinPrefetchStride() const;
272 } // end namespace llvm
274 #endif // LLVM_MC_MCSUBTARGETINFO_H