blob: b3ce523d9c0ca4da9c5a3a8156019a600ef1c4f0 [file] [log] [blame]
Andrew Scull5e1ddfa2018-08-14 10:06:54 +01001//===- 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/ADT/ArrayRef.h"
18#include "llvm/ADT/StringRef.h"
19#include "llvm/ADT/Triple.h"
20#include "llvm/MC/MCInstrItineraries.h"
21#include "llvm/MC/MCSchedule.h"
22#include "llvm/MC/SubtargetFeature.h"
23#include <algorithm>
24#include <cassert>
25#include <cstdint>
26#include <string>
27
28namespace llvm {
29
Andrew Scull5e1ddfa2018-08-14 10:06:54 +010030class MCInst;
31
32//===----------------------------------------------------------------------===//
33///
34/// Generic base class for all target subtargets.
35///
36class MCSubtargetInfo {
37 Triple TargetTriple;
38 std::string CPU; // CPU being targeted.
39 ArrayRef<SubtargetFeatureKV> ProcFeatures; // Processor feature list
40 ArrayRef<SubtargetFeatureKV> ProcDesc; // Processor descriptions
41
42 // Scheduler machine model
43 const SubtargetInfoKV *ProcSchedModels;
44 const MCWriteProcResEntry *WriteProcResTable;
45 const MCWriteLatencyEntry *WriteLatencyTable;
46 const MCReadAdvanceEntry *ReadAdvanceTable;
47 const MCSchedModel *CPUSchedModel;
48
49 const InstrStage *Stages; // Instruction itinerary stages
50 const unsigned *OperandCycles; // Itinerary operand cycles
51 const unsigned *ForwardingPaths;
52 FeatureBitset FeatureBits; // Feature bits for current CPU + FS
53
54public:
55 MCSubtargetInfo(const MCSubtargetInfo &) = default;
56 MCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS,
57 ArrayRef<SubtargetFeatureKV> PF,
58 ArrayRef<SubtargetFeatureKV> PD,
59 const SubtargetInfoKV *ProcSched,
60 const MCWriteProcResEntry *WPR, const MCWriteLatencyEntry *WL,
61 const MCReadAdvanceEntry *RA, const InstrStage *IS,
62 const unsigned *OC, const unsigned *FP);
63 MCSubtargetInfo() = delete;
64 MCSubtargetInfo &operator=(const MCSubtargetInfo &) = delete;
65 MCSubtargetInfo &operator=(MCSubtargetInfo &&) = delete;
66 virtual ~MCSubtargetInfo() = default;
67
68 const Triple &getTargetTriple() const { return TargetTriple; }
69 StringRef getCPU() const { return CPU; }
70
71 const FeatureBitset& getFeatureBits() const { return FeatureBits; }
72 void setFeatureBits(const FeatureBitset &FeatureBits_) {
73 FeatureBits = FeatureBits_;
74 }
75
76 bool hasFeature(unsigned Feature) const {
77 return FeatureBits[Feature];
78 }
79
80protected:
81 /// Initialize the scheduling model and feature bits.
82 ///
83 /// FIXME: Find a way to stick this in the constructor, since it should only
84 /// be called during initialization.
85 void InitMCProcessorInfo(StringRef CPU, StringRef FS);
86
87public:
88 /// Set the features to the default for the given CPU with an appended feature
89 /// string.
90 void setDefaultFeatures(StringRef CPU, StringRef FS);
91
92 /// Toggle a feature and return the re-computed feature bits.
93 /// This version does not change the implied bits.
94 FeatureBitset ToggleFeature(uint64_t FB);
95
96 /// Toggle a feature and return the re-computed feature bits.
97 /// This version does not change the implied bits.
98 FeatureBitset ToggleFeature(const FeatureBitset& FB);
99
100 /// Toggle a set of features and return the re-computed feature bits.
101 /// This version will also change all implied bits.
102 FeatureBitset ToggleFeature(StringRef FS);
103
104 /// Apply a feature flag and return the re-computed feature bits, including
105 /// all feature bits implied by the flag.
106 FeatureBitset ApplyFeatureFlag(StringRef FS);
107
108 /// Check whether the subtarget features are enabled/disabled as per
109 /// the provided string, ignoring all other features.
110 bool checkFeatures(StringRef FS) const;
111
112 /// Get the machine model of a CPU.
113 const MCSchedModel &getSchedModelForCPU(StringRef CPU) const;
114
115 /// Get the machine model for this subtarget's CPU.
116 const MCSchedModel &getSchedModel() const { return *CPUSchedModel; }
117
118 /// Return an iterator at the first process resource consumed by the given
119 /// scheduling class.
120 const MCWriteProcResEntry *getWriteProcResBegin(
121 const MCSchedClassDesc *SC) const {
122 return &WriteProcResTable[SC->WriteProcResIdx];
123 }
124 const MCWriteProcResEntry *getWriteProcResEnd(
125 const MCSchedClassDesc *SC) const {
126 return getWriteProcResBegin(SC) + SC->NumWriteProcResEntries;
127 }
128
129 const MCWriteLatencyEntry *getWriteLatencyEntry(const MCSchedClassDesc *SC,
130 unsigned DefIdx) const {
131 assert(DefIdx < SC->NumWriteLatencyEntries &&
132 "MachineModel does not specify a WriteResource for DefIdx");
133
134 return &WriteLatencyTable[SC->WriteLatencyIdx + DefIdx];
135 }
136
137 int getReadAdvanceCycles(const MCSchedClassDesc *SC, unsigned UseIdx,
138 unsigned WriteResID) const {
139 // TODO: The number of read advance entries in a class can be significant
140 // (~50). Consider compressing the WriteID into a dense ID of those that are
141 // used by ReadAdvance and representing them as a bitset.
142 for (const MCReadAdvanceEntry *I = &ReadAdvanceTable[SC->ReadAdvanceIdx],
143 *E = I + SC->NumReadAdvanceEntries; I != E; ++I) {
144 if (I->UseIdx < UseIdx)
145 continue;
146 if (I->UseIdx > UseIdx)
147 break;
148 // Find the first WriteResIdx match, which has the highest cycle count.
149 if (!I->WriteResourceID || I->WriteResourceID == WriteResID) {
150 return I->Cycles;
151 }
152 }
153 return 0;
154 }
155
156 /// Get scheduling itinerary of a CPU.
157 InstrItineraryData getInstrItineraryForCPU(StringRef CPU) const;
158
159 /// Initialize an InstrItineraryData instance.
160 void initInstrItins(InstrItineraryData &InstrItins) const;
161
Andrew Scullcdfcccc2018-10-05 20:58:37 +0100162 /// Resolve a variant scheduling class for the given MCInst and CPU.
163 virtual unsigned
164 resolveVariantSchedClass(unsigned SchedClass, const MCInst *MI,
165 unsigned CPUID) const {
166 return 0;
167 }
168
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100169 /// Check whether the CPU string is valid.
170 bool isCPUStringValid(StringRef CPU) const {
171 auto Found = std::lower_bound(ProcDesc.begin(), ProcDesc.end(), CPU);
172 return Found != ProcDesc.end() && StringRef(Found->Key) == CPU;
173 }
174
175 /// Returns string representation of scheduler comment
Andrew Scull5e1ddfa2018-08-14 10:06:54 +0100176 virtual std::string getSchedInfoStr(MCInst const &MCI) const {
177 return {};
178 }
179};
180
181} // end namespace llvm
182
183#endif // LLVM_MC_MCSUBTARGETINFO_H