#ifndef LLVM_MC_MCSUBTARGETINFO_H
#define LLVM_MC_MCSUBTARGETINFO_H
#include "llvm/MC/MCInstrItineraries.h"
#include "llvm/MC/SubtargetFeature.h"
#include <string>
namespace llvm {
class StringRef;
class MCSubtargetInfo {
Triple TargetTriple; std::string CPU; ArrayRef<SubtargetFeatureKV> ProcFeatures; ArrayRef<SubtargetFeatureKV> ProcDesc;
const SubtargetInfoKV *ProcSchedModels;
const MCWriteProcResEntry *WriteProcResTable;
const MCWriteLatencyEntry *WriteLatencyTable;
const MCReadAdvanceEntry *ReadAdvanceTable;
const MCSchedModel *CPUSchedModel;
const InstrStage *Stages; const unsigned *OperandCycles; const unsigned *ForwardingPaths; FeatureBitset FeatureBits;
MCSubtargetInfo() = delete;
MCSubtargetInfo &operator=(MCSubtargetInfo &&) = delete;
MCSubtargetInfo &operator=(const MCSubtargetInfo &) = delete;
public:
MCSubtargetInfo(const MCSubtargetInfo &) = default;
MCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS,
ArrayRef<SubtargetFeatureKV> PF,
ArrayRef<SubtargetFeatureKV> PD,
const SubtargetInfoKV *ProcSched,
const MCWriteProcResEntry *WPR, const MCWriteLatencyEntry *WL,
const MCReadAdvanceEntry *RA, const InstrStage *IS,
const unsigned *OC, const unsigned *FP);
const Triple &getTargetTriple() const { return TargetTriple; }
StringRef getCPU() const {
return CPU;
}
const FeatureBitset& getFeatureBits() const {
return FeatureBits;
}
void setFeatureBits(const FeatureBitset &FeatureBits_) {
FeatureBits = FeatureBits_;
}
protected:
void InitMCProcessorInfo(StringRef CPU, StringRef FS);
public:
void setDefaultFeatures(StringRef CPU, StringRef FS);
FeatureBitset ToggleFeature(uint64_t FB);
FeatureBitset ToggleFeature(const FeatureBitset& FB);
FeatureBitset ToggleFeature(StringRef FS);
FeatureBitset ApplyFeatureFlag(StringRef FS);
const MCSchedModel &getSchedModelForCPU(StringRef CPU) const;
const MCSchedModel &getSchedModel() const { return *CPUSchedModel; }
const MCWriteProcResEntry *getWriteProcResBegin(
const MCSchedClassDesc *SC) const {
return &WriteProcResTable[SC->WriteProcResIdx];
}
const MCWriteProcResEntry *getWriteProcResEnd(
const MCSchedClassDesc *SC) const {
return getWriteProcResBegin(SC) + SC->NumWriteProcResEntries;
}
const MCWriteLatencyEntry *getWriteLatencyEntry(const MCSchedClassDesc *SC,
unsigned DefIdx) const {
assert(DefIdx < SC->NumWriteLatencyEntries &&
"MachineModel does not specify a WriteResource for DefIdx");
return &WriteLatencyTable[SC->WriteLatencyIdx + DefIdx];
}
int getReadAdvanceCycles(const MCSchedClassDesc *SC, unsigned UseIdx,
unsigned WriteResID) const {
for (const MCReadAdvanceEntry *I = &ReadAdvanceTable[SC->ReadAdvanceIdx],
*E = I + SC->NumReadAdvanceEntries; I != E; ++I) {
if (I->UseIdx < UseIdx)
continue;
if (I->UseIdx > UseIdx)
break;
if (!I->WriteResourceID || I->WriteResourceID == WriteResID) {
return I->Cycles;
}
}
return 0;
}
InstrItineraryData getInstrItineraryForCPU(StringRef CPU) const;
void initInstrItins(InstrItineraryData &InstrItins) const;
bool isCPUStringValid(StringRef CPU) const {
auto Found = std::lower_bound(ProcDesc.begin(), ProcDesc.end(), CPU);
return Found != ProcDesc.end() && StringRef(Found->Key) == CPU;
}
};
}
#endif