194214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng//==-- llvm/MC/MCSubtargetInfo.h - Subtarget Information ---------*- C++ -*-==// 294214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng// 394214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng// The LLVM Compiler Infrastructure 494214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng// 594214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng// This file is distributed under the University of Illinois Open Source 694214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng// License. See LICENSE.TXT for details. 794214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng// 894214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng//===----------------------------------------------------------------------===// 994214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng// 1094214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng// This file describes the subtarget options of a Target machine. 1194214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng// 1294214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng//===----------------------------------------------------------------------===// 1394214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng 1437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#ifndef LLVM_MC_MCSUBTARGETINFO_H 1537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#define LLVM_MC_MCSUBTARGETINFO_H 1694214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng 1794214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng#include "llvm/MC/MCInstrItineraries.h" 18255f89faee13dc491cb64fbeae3c763e7e2ea4e6Chandler Carruth#include "llvm/MC/SubtargetFeature.h" 1959ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng#include <string> 2094214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng 2194214703d97d8d9dfca88174ffc7e94820a85e62Evan Chengnamespace llvm { 2294214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng 2394214703d97d8d9dfca88174ffc7e94820a85e62Evan Chengclass StringRef; 2494214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng 2594214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng//===----------------------------------------------------------------------===// 2694214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng/// 2794214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng/// MCSubtargetInfo - Generic base class for all target subtargets. 2894214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng/// 2994214703d97d8d9dfca88174ffc7e94820a85e62Evan Chengclass MCSubtargetInfo { 3059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng std::string TargetTriple; // Target triple 31ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::string CPU; // CPU being targeted. 32dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ArrayRef<SubtargetFeatureKV> ProcFeatures; // Processor feature list 33dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ArrayRef<SubtargetFeatureKV> ProcDesc; // Processor descriptions 3472d048b69705f01d48bdef7b235ec96b24290767Andrew Trick 3572d048b69705f01d48bdef7b235ec96b24290767Andrew Trick // Scheduler machine model 3672d048b69705f01d48bdef7b235ec96b24290767Andrew Trick const SubtargetInfoKV *ProcSchedModels; 3772d048b69705f01d48bdef7b235ec96b24290767Andrew Trick const MCWriteProcResEntry *WriteProcResTable; 3872d048b69705f01d48bdef7b235ec96b24290767Andrew Trick const MCWriteLatencyEntry *WriteLatencyTable; 3972d048b69705f01d48bdef7b235ec96b24290767Andrew Trick const MCReadAdvanceEntry *ReadAdvanceTable; 4037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines MCSchedModel CPUSchedModel; 4172d048b69705f01d48bdef7b235ec96b24290767Andrew Trick 422661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick const InstrStage *Stages; // Instruction itinerary stages 432661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick const unsigned *OperandCycles; // Itinerary operand cycles 44a11a6287a504d1d7503e744d14314df1e696f506Andrew Trick const unsigned *ForwardingPaths; // Forwarding paths 45ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng uint64_t FeatureBits; // Feature bits for current CPU + FS 460ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng 4794214703d97d8d9dfca88174ffc7e94820a85e62Evan Chengpublic: 4859ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng void InitMCSubtargetInfo(StringRef TT, StringRef CPU, StringRef FS, 49dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ArrayRef<SubtargetFeatureKV> PF, 50dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ArrayRef<SubtargetFeatureKV> PD, 512661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick const SubtargetInfoKV *ProcSched, 52e127dfd0b175b5a336e61fecaad7fc2aec65d95cAndrew Trick const MCWriteProcResEntry *WPR, 53e127dfd0b175b5a336e61fecaad7fc2aec65d95cAndrew Trick const MCWriteLatencyEntry *WL, 54e127dfd0b175b5a336e61fecaad7fc2aec65d95cAndrew Trick const MCReadAdvanceEntry *RA, 552661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick const InstrStage *IS, 56dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const unsigned *OC, const unsigned *FP); 570ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng 5859ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng /// getTargetTriple - Return the target triple string. 5959ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng StringRef getTargetTriple() const { 6059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng return TargetTriple; 6159ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng } 6259ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng 63ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// getCPU - Return the CPU string. 64ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines StringRef getCPU() const { 65ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return CPU; 66ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 67ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 6859ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng /// getFeatureBits - Return the feature bits. 690ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng /// 700ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng uint64_t getFeatureBits() const { 710ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng return FeatureBits; 7294214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng } 7394214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng 7437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines /// setFeatureBits - Set the feature bits. 7537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines /// 7637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines void setFeatureBits(uint64_t FeatureBits_) { FeatureBits = FeatureBits_; } 7737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 7834aadd63346b5f9b98749a306b71fcb00ee6996fAndrew Trick /// InitMCProcessorInfo - Set or change the CPU (optionally supplemented with 7934aadd63346b5f9b98749a306b71fcb00ee6996fAndrew Trick /// feature string). Recompute feature bits and scheduling model. 8034aadd63346b5f9b98749a306b71fcb00ee6996fAndrew Trick void InitMCProcessorInfo(StringRef CPU, StringRef FS); 810ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng 82773c07606e61c5090d73ea1317a0d1b0c29ec023Craig Topper /// InitCPUSchedModel - Recompute scheduling model based on CPU. 83773c07606e61c5090d73ea1317a0d1b0c29ec023Craig Topper void InitCPUSchedModel(StringRef CPU); 84773c07606e61c5090d73ea1317a0d1b0c29ec023Craig Topper 85ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng /// ToggleFeature - Toggle a feature and returns the re-computed feature 86ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng /// bits. This version does not change the implied bits. 87ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng uint64_t ToggleFeature(uint64_t FB); 88ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng 89ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng /// ToggleFeature - Toggle a feature and returns the re-computed feature 90ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng /// bits. This version will also change all implied bits. 91ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng uint64_t ToggleFeature(StringRef FS); 92ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng 932661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick /// getSchedModelForCPU - Get the machine model of a CPU. 942661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick /// 9537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines MCSchedModel getSchedModelForCPU(StringRef CPU) const; 962661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick 97e127dfd0b175b5a336e61fecaad7fc2aec65d95cAndrew Trick /// getSchedModel - Get the machine model for this subtarget's CPU. 98e127dfd0b175b5a336e61fecaad7fc2aec65d95cAndrew Trick /// 9937ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const MCSchedModel &getSchedModel() const { return CPUSchedModel; } 100e127dfd0b175b5a336e61fecaad7fc2aec65d95cAndrew Trick 10172d048b69705f01d48bdef7b235ec96b24290767Andrew Trick /// Return an iterator at the first process resource consumed by the given 10272d048b69705f01d48bdef7b235ec96b24290767Andrew Trick /// scheduling class. 10372d048b69705f01d48bdef7b235ec96b24290767Andrew Trick const MCWriteProcResEntry *getWriteProcResBegin( 10472d048b69705f01d48bdef7b235ec96b24290767Andrew Trick const MCSchedClassDesc *SC) const { 10572d048b69705f01d48bdef7b235ec96b24290767Andrew Trick return &WriteProcResTable[SC->WriteProcResIdx]; 10672d048b69705f01d48bdef7b235ec96b24290767Andrew Trick } 10772d048b69705f01d48bdef7b235ec96b24290767Andrew Trick const MCWriteProcResEntry *getWriteProcResEnd( 10872d048b69705f01d48bdef7b235ec96b24290767Andrew Trick const MCSchedClassDesc *SC) const { 10972d048b69705f01d48bdef7b235ec96b24290767Andrew Trick return getWriteProcResBegin(SC) + SC->NumWriteProcResEntries; 11072d048b69705f01d48bdef7b235ec96b24290767Andrew Trick } 11172d048b69705f01d48bdef7b235ec96b24290767Andrew Trick 11272d048b69705f01d48bdef7b235ec96b24290767Andrew Trick const MCWriteLatencyEntry *getWriteLatencyEntry(const MCSchedClassDesc *SC, 11372d048b69705f01d48bdef7b235ec96b24290767Andrew Trick unsigned DefIdx) const { 11472d048b69705f01d48bdef7b235ec96b24290767Andrew Trick assert(DefIdx < SC->NumWriteLatencyEntries && 11572d048b69705f01d48bdef7b235ec96b24290767Andrew Trick "MachineModel does not specify a WriteResource for DefIdx"); 11672d048b69705f01d48bdef7b235ec96b24290767Andrew Trick 11772d048b69705f01d48bdef7b235ec96b24290767Andrew Trick return &WriteLatencyTable[SC->WriteLatencyIdx + DefIdx]; 11872d048b69705f01d48bdef7b235ec96b24290767Andrew Trick } 11972d048b69705f01d48bdef7b235ec96b24290767Andrew Trick 12072d048b69705f01d48bdef7b235ec96b24290767Andrew Trick int getReadAdvanceCycles(const MCSchedClassDesc *SC, unsigned UseIdx, 12172d048b69705f01d48bdef7b235ec96b24290767Andrew Trick unsigned WriteResID) const { 12285c7b6108f8c8cea77d0bce30343f736f6c15981Andrew Trick // TODO: The number of read advance entries in a class can be significant 12385c7b6108f8c8cea77d0bce30343f736f6c15981Andrew Trick // (~50). Consider compressing the WriteID into a dense ID of those that are 12485c7b6108f8c8cea77d0bce30343f736f6c15981Andrew Trick // used by ReadAdvance and representing them as a bitset. 12572d048b69705f01d48bdef7b235ec96b24290767Andrew Trick for (const MCReadAdvanceEntry *I = &ReadAdvanceTable[SC->ReadAdvanceIdx], 12672d048b69705f01d48bdef7b235ec96b24290767Andrew Trick *E = I + SC->NumReadAdvanceEntries; I != E; ++I) { 12772d048b69705f01d48bdef7b235ec96b24290767Andrew Trick if (I->UseIdx < UseIdx) 12872d048b69705f01d48bdef7b235ec96b24290767Andrew Trick continue; 12972d048b69705f01d48bdef7b235ec96b24290767Andrew Trick if (I->UseIdx > UseIdx) 13072d048b69705f01d48bdef7b235ec96b24290767Andrew Trick break; 13172d048b69705f01d48bdef7b235ec96b24290767Andrew Trick // Find the first WriteResIdx match, which has the highest cycle count. 13272d048b69705f01d48bdef7b235ec96b24290767Andrew Trick if (!I->WriteResourceID || I->WriteResourceID == WriteResID) { 13372d048b69705f01d48bdef7b235ec96b24290767Andrew Trick return I->Cycles; 13472d048b69705f01d48bdef7b235ec96b24290767Andrew Trick } 13572d048b69705f01d48bdef7b235ec96b24290767Andrew Trick } 13672d048b69705f01d48bdef7b235ec96b24290767Andrew Trick return 0; 13772d048b69705f01d48bdef7b235ec96b24290767Andrew Trick } 13872d048b69705f01d48bdef7b235ec96b24290767Andrew Trick 13994214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng /// getInstrItineraryForCPU - Get scheduling itinerary of a CPU. 14094214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng /// 14194214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng InstrItineraryData getInstrItineraryForCPU(StringRef CPU) const; 14299ab6c6035aec3c0e9b0cc5b76a4666fc5fd7b7bAndrew Trick 14399ab6c6035aec3c0e9b0cc5b76a4666fc5fd7b7bAndrew Trick /// Initialize an InstrItineraryData instance. 14499ab6c6035aec3c0e9b0cc5b76a4666fc5fd7b7bAndrew Trick void initInstrItins(InstrItineraryData &InstrItins) const; 145ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 146ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// Check whether the CPU string is valid. 147ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines bool isCPUStringValid(StringRef CPU) { 148ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines auto Found = std::find_if(ProcDesc.begin(), ProcDesc.end(), 149ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines [=](const SubtargetFeatureKV &KV) { 150ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return CPU == KV.Key; 151ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines }); 152ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return Found != ProcDesc.end(); 153ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 15494214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng}; 15594214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng 15694214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng} // End llvm namespace 15794214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng 15894214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng#endif 159