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 17de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar#include "llvm/ADT/ArrayRef.h" 1894214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng#include "llvm/MC/MCInstrItineraries.h" 19255f89faee13dc491cb64fbeae3c763e7e2ea4e6Chandler Carruth#include "llvm/MC/SubtargetFeature.h" 2059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng#include <string> 2194214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng 2294214703d97d8d9dfca88174ffc7e94820a85e62Evan Chengnamespace llvm { 2394214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng 2494214703d97d8d9dfca88174ffc7e94820a85e62Evan Chengclass StringRef; 2594214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng 2694214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng//===----------------------------------------------------------------------===// 2794214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng/// 2894214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng/// MCSubtargetInfo - Generic base class for all target subtargets. 2994214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng/// 3094214703d97d8d9dfca88174ffc7e94820a85e62Evan Chengclass MCSubtargetInfo { 316948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar Triple TargetTriple; // Target triple 32ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines std::string CPU; // CPU being targeted. 33dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ArrayRef<SubtargetFeatureKV> ProcFeatures; // Processor feature list 34dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ArrayRef<SubtargetFeatureKV> ProcDesc; // Processor descriptions 3572d048b69705f01d48bdef7b235ec96b24290767Andrew Trick 3672d048b69705f01d48bdef7b235ec96b24290767Andrew Trick // Scheduler machine model 3772d048b69705f01d48bdef7b235ec96b24290767Andrew Trick const SubtargetInfoKV *ProcSchedModels; 3872d048b69705f01d48bdef7b235ec96b24290767Andrew Trick const MCWriteProcResEntry *WriteProcResTable; 3972d048b69705f01d48bdef7b235ec96b24290767Andrew Trick const MCWriteLatencyEntry *WriteLatencyTable; 4072d048b69705f01d48bdef7b235ec96b24290767Andrew Trick const MCReadAdvanceEntry *ReadAdvanceTable; 41f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const MCSchedModel *CPUSchedModel; 4272d048b69705f01d48bdef7b235ec96b24290767Andrew Trick 432661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick const InstrStage *Stages; // Instruction itinerary stages 442661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick const unsigned *OperandCycles; // Itinerary operand cycles 45a11a6287a504d1d7503e744d14314df1e696f506Andrew Trick const unsigned *ForwardingPaths; // Forwarding paths 466948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar FeatureBitset FeatureBits; // Feature bits for current CPU + FS 470ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng 48f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MCSubtargetInfo() = delete; 49f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MCSubtargetInfo &operator=(MCSubtargetInfo &&) = delete; 50f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MCSubtargetInfo &operator=(const MCSubtargetInfo &) = delete; 51f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 5294214703d97d8d9dfca88174ffc7e94820a85e62Evan Chengpublic: 53f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MCSubtargetInfo(const MCSubtargetInfo &) = default; 54f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MCSubtargetInfo(const Triple &TT, StringRef CPU, StringRef FS, 55f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar ArrayRef<SubtargetFeatureKV> PF, 56f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar ArrayRef<SubtargetFeatureKV> PD, 57f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const SubtargetInfoKV *ProcSched, 58f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const MCWriteProcResEntry *WPR, const MCWriteLatencyEntry *WL, 59f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const MCReadAdvanceEntry *RA, const InstrStage *IS, 60f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const unsigned *OC, const unsigned *FP); 610ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng 6259ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng /// getTargetTriple - Return the target triple string. 636948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const Triple &getTargetTriple() const { return TargetTriple; } 6459ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng 65ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// getCPU - Return the CPU string. 66ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines StringRef getCPU() const { 67ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines return CPU; 68ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 69ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 7059ee62d2418df8db499eca1ae17f5900dc2dcbbaEvan Cheng /// getFeatureBits - Return the feature bits. 710ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng /// 726948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const FeatureBitset& getFeatureBits() const { 730ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng return FeatureBits; 7494214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng } 7594214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng 7637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines /// setFeatureBits - Set the feature bits. 7737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines /// 786948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar void setFeatureBits(const FeatureBitset &FeatureBits_) { 796948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar FeatureBits = FeatureBits_; 806948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar } 8137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines 82f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarprotected: 83f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar /// Initialize the scheduling model and feature bits. 84f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar /// 85f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar /// FIXME: Find a way to stick this in the constructor, since it should only 86f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar /// be called during initialization. 8734aadd63346b5f9b98749a306b71fcb00ee6996fAndrew Trick void InitMCProcessorInfo(StringRef CPU, StringRef FS); 880ddff1b5359433faf2eb1c4ff5320ddcbd42f52fEvan Cheng 89f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarpublic: 90f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar /// Set the features to the default for the given CPU with an appended feature 91f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar /// string. 92f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar void setDefaultFeatures(StringRef CPU, StringRef FS); 93773c07606e61c5090d73ea1317a0d1b0c29ec023Craig Topper 94ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng /// ToggleFeature - Toggle a feature and returns the re-computed feature 95ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng /// bits. This version does not change the implied bits. 966948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar FeatureBitset ToggleFeature(uint64_t FB); 97ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng 98ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng /// ToggleFeature - Toggle a feature and returns the re-computed feature 996948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// bits. This version does not change the implied bits. 1006948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar FeatureBitset ToggleFeature(const FeatureBitset& FB); 1016948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 1026948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// ToggleFeature - Toggle a set of features and returns the re-computed 1036948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// feature bits. This version will also change all implied bits. 1046948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar FeatureBitset ToggleFeature(StringRef FS); 1056948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar 1066948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// Apply a feature flag and return the re-computed feature bits, including 1076948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar /// all feature bits implied by the flag. 1086948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar FeatureBitset ApplyFeatureFlag(StringRef FS); 109ffc0e73046f737d75e0a62b3a83ef19bcef111e3Evan Cheng 1102661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick /// getSchedModelForCPU - Get the machine model of a CPU. 1112661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick /// 112f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const MCSchedModel &getSchedModelForCPU(StringRef CPU) const; 1132661b411ccc81b1fe19194d3f43b2630cbef3f28Andrew Trick 114f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar /// Get the machine model for this subtarget's CPU. 115f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar const MCSchedModel &getSchedModel() const { return *CPUSchedModel; } 116e127dfd0b175b5a336e61fecaad7fc2aec65d95cAndrew Trick 11772d048b69705f01d48bdef7b235ec96b24290767Andrew Trick /// Return an iterator at the first process resource consumed by the given 11872d048b69705f01d48bdef7b235ec96b24290767Andrew Trick /// scheduling class. 11972d048b69705f01d48bdef7b235ec96b24290767Andrew Trick const MCWriteProcResEntry *getWriteProcResBegin( 12072d048b69705f01d48bdef7b235ec96b24290767Andrew Trick const MCSchedClassDesc *SC) const { 12172d048b69705f01d48bdef7b235ec96b24290767Andrew Trick return &WriteProcResTable[SC->WriteProcResIdx]; 12272d048b69705f01d48bdef7b235ec96b24290767Andrew Trick } 12372d048b69705f01d48bdef7b235ec96b24290767Andrew Trick const MCWriteProcResEntry *getWriteProcResEnd( 12472d048b69705f01d48bdef7b235ec96b24290767Andrew Trick const MCSchedClassDesc *SC) const { 12572d048b69705f01d48bdef7b235ec96b24290767Andrew Trick return getWriteProcResBegin(SC) + SC->NumWriteProcResEntries; 12672d048b69705f01d48bdef7b235ec96b24290767Andrew Trick } 12772d048b69705f01d48bdef7b235ec96b24290767Andrew Trick 12872d048b69705f01d48bdef7b235ec96b24290767Andrew Trick const MCWriteLatencyEntry *getWriteLatencyEntry(const MCSchedClassDesc *SC, 12972d048b69705f01d48bdef7b235ec96b24290767Andrew Trick unsigned DefIdx) const { 13072d048b69705f01d48bdef7b235ec96b24290767Andrew Trick assert(DefIdx < SC->NumWriteLatencyEntries && 13172d048b69705f01d48bdef7b235ec96b24290767Andrew Trick "MachineModel does not specify a WriteResource for DefIdx"); 13272d048b69705f01d48bdef7b235ec96b24290767Andrew Trick 13372d048b69705f01d48bdef7b235ec96b24290767Andrew Trick return &WriteLatencyTable[SC->WriteLatencyIdx + DefIdx]; 13472d048b69705f01d48bdef7b235ec96b24290767Andrew Trick } 13572d048b69705f01d48bdef7b235ec96b24290767Andrew Trick 13672d048b69705f01d48bdef7b235ec96b24290767Andrew Trick int getReadAdvanceCycles(const MCSchedClassDesc *SC, unsigned UseIdx, 13772d048b69705f01d48bdef7b235ec96b24290767Andrew Trick unsigned WriteResID) const { 13885c7b6108f8c8cea77d0bce30343f736f6c15981Andrew Trick // TODO: The number of read advance entries in a class can be significant 13985c7b6108f8c8cea77d0bce30343f736f6c15981Andrew Trick // (~50). Consider compressing the WriteID into a dense ID of those that are 14085c7b6108f8c8cea77d0bce30343f736f6c15981Andrew Trick // used by ReadAdvance and representing them as a bitset. 14172d048b69705f01d48bdef7b235ec96b24290767Andrew Trick for (const MCReadAdvanceEntry *I = &ReadAdvanceTable[SC->ReadAdvanceIdx], 14272d048b69705f01d48bdef7b235ec96b24290767Andrew Trick *E = I + SC->NumReadAdvanceEntries; I != E; ++I) { 14372d048b69705f01d48bdef7b235ec96b24290767Andrew Trick if (I->UseIdx < UseIdx) 14472d048b69705f01d48bdef7b235ec96b24290767Andrew Trick continue; 14572d048b69705f01d48bdef7b235ec96b24290767Andrew Trick if (I->UseIdx > UseIdx) 14672d048b69705f01d48bdef7b235ec96b24290767Andrew Trick break; 14772d048b69705f01d48bdef7b235ec96b24290767Andrew Trick // Find the first WriteResIdx match, which has the highest cycle count. 14872d048b69705f01d48bdef7b235ec96b24290767Andrew Trick if (!I->WriteResourceID || I->WriteResourceID == WriteResID) { 14972d048b69705f01d48bdef7b235ec96b24290767Andrew Trick return I->Cycles; 15072d048b69705f01d48bdef7b235ec96b24290767Andrew Trick } 15172d048b69705f01d48bdef7b235ec96b24290767Andrew Trick } 15272d048b69705f01d48bdef7b235ec96b24290767Andrew Trick return 0; 15372d048b69705f01d48bdef7b235ec96b24290767Andrew Trick } 15472d048b69705f01d48bdef7b235ec96b24290767Andrew Trick 15594214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng /// getInstrItineraryForCPU - Get scheduling itinerary of a CPU. 15694214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng /// 15794214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng InstrItineraryData getInstrItineraryForCPU(StringRef CPU) const; 15899ab6c6035aec3c0e9b0cc5b76a4666fc5fd7b7bAndrew Trick 15999ab6c6035aec3c0e9b0cc5b76a4666fc5fd7b7bAndrew Trick /// Initialize an InstrItineraryData instance. 16099ab6c6035aec3c0e9b0cc5b76a4666fc5fd7b7bAndrew Trick void initInstrItins(InstrItineraryData &InstrItins) const; 161ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 162ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines /// Check whether the CPU string is valid. 163f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool isCPUStringValid(StringRef CPU) const { 164f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar auto Found = std::lower_bound(ProcDesc.begin(), ProcDesc.end(), CPU); 165f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return Found != ProcDesc.end() && StringRef(Found->Key) == CPU; 166ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines } 16794214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng}; 16894214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng 16994214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng} // End llvm namespace 17094214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng 17194214703d97d8d9dfca88174ffc7e94820a85e62Evan Cheng#endif 172