//===- MCSchedule.cpp - Scheduling ------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // // This file defines the default scheduling model. // //===----------------------------------------------------------------------===// #include "llvm/MC/MCSchedule.h" #include "llvm/MC/MCSubtargetInfo.h" #include using namespace llvm; static_assert(std::is_pod::value, "We shouldn't have a static constructor here"); const MCSchedModel MCSchedModel::Default = {DefaultIssueWidth, DefaultMicroOpBufferSize, DefaultLoopMicroOpBufferSize, DefaultLoadLatency, DefaultHighLatency, DefaultMispredictPenalty, false, true, 0, nullptr, nullptr, 0, 0, nullptr}; int MCSchedModel::computeInstrLatency(const MCSubtargetInfo &STI, const MCSchedClassDesc &SCDesc) { int Latency = 0; for (unsigned DefIdx = 0, DefEnd = SCDesc.NumWriteLatencyEntries; DefIdx != DefEnd; ++DefIdx) { // Lookup the definition's write latency in SubtargetInfo. const MCWriteLatencyEntry *WLEntry = STI.getWriteLatencyEntry(&SCDesc, DefIdx); // Early exit if we found an invalid latency. if (WLEntry->Cycles < 0) return WLEntry->Cycles; Latency = std::max(Latency, static_cast(WLEntry->Cycles)); } return Latency; } Optional MCSchedModel::getReciprocalThroughput(const MCSubtargetInfo &STI, const MCSchedClassDesc &SCDesc) { Optional Throughput; const MCSchedModel &SchedModel = STI.getSchedModel(); for (const MCWriteProcResEntry *WPR = STI.getWriteProcResBegin(&SCDesc), *WEnd = STI.getWriteProcResEnd(&SCDesc); WPR != WEnd; ++WPR) { if (WPR->Cycles) { unsigned NumUnits = SchedModel.getProcResource(WPR->ProcResourceIdx)->NumUnits; double Temp = NumUnits * 1.0 / WPR->Cycles; Throughput = Throughput.hasValue() ? std::min(Throughput.getValue(), Temp) : Temp; } } if (Throughput.hasValue()) return 1 / Throughput.getValue(); return Throughput; }