1 //===- TargetSubtargetInfo.cpp - General Target Information ----------------==// 2 // 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 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 /// \file This file describes the general parts of a Subtarget. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "llvm/CodeGen/TargetSubtargetInfo.h" 14 #include "llvm/ADT/Optional.h" 15 #include "llvm/CodeGen/MachineInstr.h" 16 #include "llvm/CodeGen/TargetInstrInfo.h" 17 #include "llvm/CodeGen/TargetSchedule.h" 18 #include "llvm/MC/MCInst.h" 19 #include "llvm/Support/Format.h" 20 #include "llvm/Support/raw_ostream.h" 21 #include <string> 22 23 using namespace llvm; 24 25 TargetSubtargetInfo::TargetSubtargetInfo( 26 const Triple &TT, StringRef CPU, StringRef FS, 27 ArrayRef<SubtargetFeatureKV> PF, ArrayRef<SubtargetFeatureKV> PD, 28 const SubtargetInfoKV *ProcSched, const MCWriteProcResEntry *WPR, 29 const MCWriteLatencyEntry *WL, const MCReadAdvanceEntry *RA, 30 const InstrStage *IS, const unsigned *OC, const unsigned *FP) 31 : MCSubtargetInfo(TT, CPU, FS, PF, PD, ProcSched, WPR, WL, RA, IS, OC, FP) { 32 } 33 34 TargetSubtargetInfo::~TargetSubtargetInfo() = default; 35 36 bool TargetSubtargetInfo::enableAtomicExpand() const { 37 return true; 38 } 39 40 bool TargetSubtargetInfo::enableIndirectBrExpand() const { 41 return false; 42 } 43 44 bool TargetSubtargetInfo::enableMachineScheduler() const { 45 return false; 46 } 47 48 bool TargetSubtargetInfo::enableJoinGlobalCopies() const { 49 return enableMachineScheduler(); 50 } 51 52 bool TargetSubtargetInfo::enableRALocalReassignment( 53 CodeGenOpt::Level OptLevel) const { 54 return true; 55 } 56 57 bool TargetSubtargetInfo::enableAdvancedRASplitCost() const { 58 return false; 59 } 60 61 bool TargetSubtargetInfo::enablePostRAScheduler() const { 62 return getSchedModel().PostRAScheduler; 63 } 64 65 bool TargetSubtargetInfo::useAA() const { 66 return false; 67 } 68 69 static std::string createSchedInfoStr(unsigned Latency, double RThroughput) { 70 static const char *SchedPrefix = " sched: ["; 71 std::string Comment; 72 raw_string_ostream CS(Comment); 73 if (RThroughput != 0.0) 74 CS << SchedPrefix << Latency << format(":%2.2f", RThroughput) 75 << "]"; 76 else 77 CS << SchedPrefix << Latency << ":?]"; 78 CS.flush(); 79 return Comment; 80 } 81 82 /// Returns string representation of scheduler comment 83 std::string TargetSubtargetInfo::getSchedInfoStr(const MachineInstr &MI) const { 84 if (MI.isPseudo() || MI.isTerminator()) 85 return std::string(); 86 // We don't cache TSchedModel because it depends on TargetInstrInfo 87 // that could be changed during the compilation 88 TargetSchedModel TSchedModel; 89 TSchedModel.init(this); 90 unsigned Latency = TSchedModel.computeInstrLatency(&MI); 91 92 // Add extra latency due to forwarding delays. 93 const MCSchedClassDesc &SCDesc = *TSchedModel.resolveSchedClass(&MI); 94 Latency += 95 MCSchedModel::getForwardingDelayCycles(getReadAdvanceEntries(SCDesc)); 96 97 double RThroughput = TSchedModel.computeReciprocalThroughput(&MI); 98 return createSchedInfoStr(Latency, RThroughput); 99 } 100 101 /// Returns string representation of scheduler comment 102 std::string TargetSubtargetInfo::getSchedInfoStr(MCInst const &MCI) const { 103 // We don't cache TSchedModel because it depends on TargetInstrInfo 104 // that could be changed during the compilation 105 TargetSchedModel TSchedModel; 106 TSchedModel.init(this); 107 unsigned Latency; 108 if (TSchedModel.hasInstrSchedModel()) { 109 Latency = TSchedModel.computeInstrLatency(MCI); 110 // Add extra latency due to forwarding delays. 111 const MCSchedModel &SM = *TSchedModel.getMCSchedModel(); 112 unsigned SClassID = getInstrInfo()->get(MCI.getOpcode()).getSchedClass(); 113 while (SM.getSchedClassDesc(SClassID)->isVariant()) 114 SClassID = resolveVariantSchedClass(SClassID, &MCI, SM.ProcID); 115 const MCSchedClassDesc &SCDesc = *SM.getSchedClassDesc(SClassID); 116 Latency += 117 MCSchedModel::getForwardingDelayCycles(getReadAdvanceEntries(SCDesc)); 118 } else if (TSchedModel.hasInstrItineraries()) { 119 auto *ItinData = TSchedModel.getInstrItineraries(); 120 Latency = ItinData->getStageLatency( 121 getInstrInfo()->get(MCI.getOpcode()).getSchedClass()); 122 } else 123 return std::string(); 124 double RThroughput = TSchedModel.computeReciprocalThroughput(MCI); 125 return createSchedInfoStr(Latency, RThroughput); 126 } 127 128 void TargetSubtargetInfo::mirFileLoaded(MachineFunction &MF) const { 129 } 130