void computeProcResourceMasks(const MCSchedModel &SM, SmallVectorImpl<uint64_t> &Masks) { unsigned ProcResourceID = 0; // Create a unique bitmask for every processor resource unit. // Skip resource at index 0, since it always references 'InvalidUnit'. Masks.resize(SM.getNumProcResourceKinds()); for (unsigned I = 1, E = SM.getNumProcResourceKinds(); I < E; ++I) { const MCProcResourceDesc &Desc = *SM.getProcResource(I); if (Desc.SubUnitsIdxBegin) continue; Masks[I] = 1ULL << ProcResourceID; ProcResourceID++; } // Create a unique bitmask for every processor resource group. for (unsigned I = 1, E = SM.getNumProcResourceKinds(); I < E; ++I) { const MCProcResourceDesc &Desc = *SM.getProcResource(I); if (!Desc.SubUnitsIdxBegin) continue; Masks[I] = 1ULL << ProcResourceID; for (unsigned U = 0; U < Desc.NumUnits; ++U) { uint64_t OtherMask = Masks[Desc.SubUnitsIdxBegin[U]]; Masks[I] |= OtherMask; } ProcResourceID++; } }
void RegisterFile::initialize(const MCSchedModel &SM, unsigned NumRegs) { // Create a default register file that "sees" all the machine registers // declared by the target. The number of physical registers in the default // register file is set equal to `NumRegs`. A value of zero for `NumRegs` // means: this register file has an unbounded number of physical registers. addRegisterFile({} /* all registers */, NumRegs); if (!SM.hasExtraProcessorInfo()) return; // For each user defined register file, allocate a RegisterMappingTracker // object. The size of every register file, as well as the mapping between // register files and register classes is specified via tablegen. const MCExtraProcessorInfo &Info = SM.getExtraProcessorInfo(); for (unsigned I = 0, E = Info.NumRegisterFiles; I < E; ++I) { const MCRegisterFileDesc &RF = Info.RegisterFiles[I]; // Skip invalid register files with zero physical registers. unsigned Length = RF.NumRegisterCostEntries; if (!RF.NumPhysRegs) continue; // The cost of a register definition is equivalent to the number of // physical registers that are allocated at register renaming stage. const MCRegisterCostEntry *FirstElt = &Info.RegisterCostTable[RF.RegisterCostEntryIdx]; addRegisterFile(ArrayRef<MCRegisterCostEntry>(FirstElt, Length), RF.NumPhysRegs); } }
/// \brief Gets latency information for \p Inst, based on \p DC information. /// \return The maximum expected latency over all the definitions or -1 /// if no information is available. static int getLatency(LLVMDisasmContext *DC, const MCInst &Inst) { // Try to compute scheduling information. const MCSubtargetInfo *STI = DC->getSubtargetInfo(); const MCSchedModel SCModel = STI->getSchedModel(); const int NoInformationAvailable = -1; // Check if we have a scheduling model for instructions. if (!SCModel.hasInstrSchedModel()) // Try to fall back to the itinerary model if the scheduling model doesn't // have a scheduling table. Note the default does not have a table. return getItineraryLatency(DC, Inst); // Get the scheduling class of the requested instruction. const MCInstrDesc& Desc = DC->getInstrInfo()->get(Inst.getOpcode()); unsigned SCClass = Desc.getSchedClass(); const MCSchedClassDesc *SCDesc = SCModel.getSchedClassDesc(SCClass); // Resolving the variant SchedClass requires an MI to pass to // SubTargetInfo::resolveSchedClass. if (!SCDesc || !SCDesc->isValid() || SCDesc->isVariant()) return NoInformationAvailable; // Compute output latency. 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); Latency = std::max(Latency, WLEntry->Cycles); } return Latency; }
RetireControlUnit::RetireControlUnit(const MCSchedModel &SM) : NextAvailableSlotIdx(0), CurrentInstructionSlotIdx(0), AvailableSlots(SM.MicroOpBufferSize), MaxRetirePerCycle(0) { // Check if the scheduling model provides extra information about the machine // processor. If so, then use that information to set the reorder buffer size // and the maximum number of instructions retired per cycle. if (SM.hasExtraProcessorInfo()) { const MCExtraProcessorInfo &EPI = SM.getExtraProcessorInfo(); if (EPI.ReorderBufferSize) AvailableSlots = EPI.ReorderBufferSize; MaxRetirePerCycle = EPI.MaxRetirePerCycle; } assert(AvailableSlots && "Invalid reorder buffer size!"); Queue.resize(AvailableSlots); }