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 /// Generic base class for all target subtargets.
35 class MCSubtargetInfo
{
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
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
];
80 /// Initialize the scheduling model and feature bits.
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
);
87 /// Set the features to the default for the given CPU with an appended feature
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
)
145 if (I
->UseIdx
> UseIdx
)
147 // Find the first WriteResIdx match, which has the highest cycle count.
148 if (!I
->WriteResourceID
|| I
->WriteResourceID
== WriteResID
) {
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.
173 resolveVariantSchedClass(unsigned SchedClass
, const MCInst
*MI
,
174 unsigned CPUID
) const {
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