/// Return the slots this instruction can execute out of unsigned HexagonMCInstrInfo::getUnits(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCInst const &MCI) { const InstrItinerary *II = STI.getSchedModel().InstrItineraries; int SchedClass = HexagonMCInstrInfo::getDesc(MCII, MCI).getSchedClass(); return ((II[SchedClass].FirstStage + HexagonStages)->getUnits()); }
Optional<double> MCSchedModel::getReciprocalThroughput(const MCSubtargetInfo &STI, const MCSchedClassDesc &SCDesc) { Optional<double> Throughput; const MCSchedModel &SM = STI.getSchedModel(); const MCWriteProcResEntry *I = STI.getWriteProcResBegin(&SCDesc); const MCWriteProcResEntry *E = STI.getWriteProcResEnd(&SCDesc); for (; I != E; ++I) { if (!I->Cycles) continue; unsigned NumUnits = SM.getProcResource(I->ProcResourceIdx)->NumUnits; double Temp = NumUnits * 1.0 / I->Cycles; Throughput = Throughput ? std::min(Throughput.getValue(), Temp) : Temp; } return Throughput ? 1 / Throughput.getValue() : Throughput; }
void DispatchStage::updateRAWDependencies(ReadState &RS, const MCSubtargetInfo &STI) { SmallVector<WriteRef, 4> DependentWrites; collectWrites(DependentWrites, RS.getRegisterID()); RS.setDependentWrites(DependentWrites.size()); // We know that this read depends on all the writes in DependentWrites. // For each write, check if we have ReadAdvance information, and use it // to figure out in how many cycles this read becomes available. const ReadDescriptor &RD = RS.getDescriptor(); const MCSchedModel &SM = STI.getSchedModel(); const MCSchedClassDesc *SC = SM.getSchedClassDesc(RD.SchedClassID); for (WriteRef &WR : DependentWrites) { WriteState &WS = *WR.getWriteState(); unsigned WriteResID = WS.getWriteResourceID(); int ReadAdvance = STI.getReadAdvanceCycles(SC, RD.UseIndex, WriteResID); WS.addUser(&RS, ReadAdvance); } }
unsigned HexagonMCInstrInfo::getOtherReservedSlots(MCInstrInfo const &MCII, MCSubtargetInfo const &STI, MCInst const &MCI) { const InstrItinerary *II = STI.getSchedModel().InstrItineraries; int SchedClass = HexagonMCInstrInfo::getDesc(MCII, MCI).getSchedClass(); unsigned Slots = 0; // FirstStage are slots that this instruction can execute in. // FirstStage+1 are slots that are also consumed by this instruction. // For example: vmemu can only execute in slot 0 but also consumes slot 1. for (unsigned Stage = II[SchedClass].FirstStage + 1; Stage < II[SchedClass].LastStage; ++Stage) { unsigned Units = (Stage + HexagonStages)->getUnits(); if (Units > HexagonGetLastSlot()) break; // fyi: getUnits() will return 0x1, 0x2, 0x4 or 0x8 Slots |= Units; } // if 0 is returned, then no additional slots are consumed by this inst. return Slots; }