Lines Matching +full:resource +full:- +full:id
1 //===--------------------- InstrBuilder.cpp ---------------------*- C++ -*-===//
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
12 //===----------------------------------------------------------------------===//
24 #define DEBUG_TYPE "llvm-mca-instrbuilder"
29 char RecycledInstErr::ID = 0; member in llvm::mca::RecycledInstErr
43 static void initializeUsedResources(InstrDesc &ID, in initializeUsedResources() argument
56 // of "consumed" processor resources and resource cycles, the logic in in initializeUsedResources()
57 // ExpandProcResource() doesn't update the number of resource cycles in initializeUsedResources()
58 // contributed by a "Super" resource to a group. in initializeUsedResources()
59 // We need to take this into account when we find that a processor resource is in initializeUsedResources()
61 // This map stores the number of cycles contributed by sub-resources that are in initializeUsedResources()
62 // part of a "Super" resource. The key value is the "Super" resource mask ID. in initializeUsedResources()
72 const MCProcResourceDesc &PR = *SM.getProcResource(PRE->ProcResourceIdx); in initializeUsedResources()
73 if (!PRE->ReleaseAtCycle) { in initializeUsedResources()
76 << "Ignoring invalid write of zero cycles on processor resource " in initializeUsedResources()
84 uint64_t Mask = ProcResourceMasks[PRE->ProcResourceIdx]; in initializeUsedResources()
93 CycleSegment RCy(0, PRE->ReleaseAtCycle, false); in initializeUsedResources()
97 SuperResources[Super] += PRE->ReleaseAtCycle; in initializeUsedResources()
101 ID.MustIssueImmediately = AllInOrderResources && AnyDispatchHazards; in initializeUsedResources()
103 // Sort elements by mask popcount, so that we prioritize resource units over in initializeUsedResources()
104 // resource groups, and smaller groups over larger groups. in initializeUsedResources()
120 // are partially overlapping resource groups. in initializeUsedResources()
121 ID.HasPartiallyOverlappingGroups = false; in initializeUsedResources()
131 ID.Resources.emplace_back(A); in initializeUsedResources()
137 // Remove the leading 1 from the resource group mask. in initializeUsedResources()
140 ID.HasPartiallyOverlappingGroups = true; in initializeUsedResources()
149 B.second.CS.subtract(A.second.size() - SuperResources[A.first]); in initializeUsedResources()
156 // A SchedWrite may specify a number of cycles in which a resource group in initializeUsedResources()
164 // Resource units HWPort0 and HWPort1 are both used for 2cy. in initializeUsedResources()
165 // Resource group HWPort01 is the union of HWPort0 and HWPort1. in initializeUsedResources()
173 for (ResourcePlusCycles &RPC : ID.Resources) { in initializeUsedResources()
175 // Remove the leading 1 from the resource group mask. in initializeUsedResources()
189 if (PR.BufferSize == -1) in initializeUsedResources()
198 ID.UsedBuffers = Buffers.getZExtValue(); in initializeUsedResources()
199 ID.UsedProcResUnits = UsedResourceUnits; in initializeUsedResources()
200 ID.UsedProcResGroups = UsedResourceGroups; in initializeUsedResources()
203 for (const std::pair<uint64_t, ResourceUsage> &R : ID.Resources) in initializeUsedResources()
208 uint64_t BufferIDs = ID.UsedBuffers; in initializeUsedResources()
210 uint64_t Current = BufferIDs & (-BufferIDs); in initializeUsedResources()
214 dbgs() << "\t\t Used Units=" << format_hex(ID.UsedProcResUnits, 16) << '\n'; in initializeUsedResources()
215 dbgs() << "\t\tUsed Groups=" << format_hex(ID.UsedProcResGroups, 16) in initializeUsedResources()
218 << ID.HasPartiallyOverlappingGroups << '\n'; in initializeUsedResources()
222 static void computeMaxLatency(InstrDesc &ID, const MCInstrDesc &MCDesc, in computeMaxLatency() argument
229 ID.MaxLatency = CallLatency; in computeMaxLatency()
236 ID.MaxLatency = Latency < 0 ? CallLatency : static_cast<unsigned>(Latency); in computeMaxLatency()
246 --NumExplicitDefs; in verifyOperands()
256 const MCOperand &Op = MCI.getOperand(MCDesc.getNumOperands() - 1); in verifyOperands()
268 void InstrBuilder::populateWrites(InstrDesc &ID, const MCInst &MCI, in populateWrites() argument
284 // These assumptions work quite well for most out-of-order in-tree targets in populateWrites()
290 // The algorithm allows non-register operands between register operand in populateWrites()
292 // implicit operand increment (-mtriple=armv7): in populateWrites()
312 // non-register operands between register definitions. The optional in populateWrites()
313 // definition is still at index #(NumOperands-1). in populateWrites()
315 // According to assumption 2. register reads start at #(NumExplicitDefs-1). in populateWrites()
324 unsigned NumVariadicOps = MCI.getNumOperands() - MCDesc.getNumOperands(); in populateWrites()
325 ID.Writes.resize(TotalDefs + NumVariadicOps); in populateWrites()
326 // Iterate over the operands list, and skip non-register or constant register in populateWrites()
330 unsigned OptionalDefIdx = MCDesc.getNumOperands() - 1; in populateWrites()
346 WriteDescriptor &Write = ID.Writes[CurrentDef]; in populateWrites()
353 WLE.Cycles < 0 ? ID.MaxLatency : static_cast<unsigned>(WLE.Cycles); in populateWrites()
357 Write.Latency = ID.MaxLatency; in populateWrites()
373 WriteDescriptor &Write = ID.Writes[Index]; in populateWrites()
381 WLE.Cycles < 0 ? ID.MaxLatency : static_cast<unsigned>(WLE.Cycles); in populateWrites()
385 Write.Latency = ID.MaxLatency; in populateWrites()
400 WriteDescriptor &Write = ID.Writes[NumExplicitDefs + NumImplicitDefs]; in populateWrites()
403 Write.Latency = ID.MaxLatency; in populateWrites()
426 WriteDescriptor &Write = ID.Writes[CurrentDef]; in populateWrites()
429 Write.Latency = ID.MaxLatency; in populateWrites()
440 ID.Writes.resize(CurrentDef); in populateWrites()
443 void InstrBuilder::populateReads(InstrDesc &ID, const MCInst &MCI, in populateReads() argument
446 unsigned NumExplicitUses = MCDesc.getNumOperands() - MCDesc.getNumDefs(); in populateReads()
450 --NumExplicitUses; in populateReads()
451 unsigned NumVariadicOps = MCI.getNumOperands() - MCDesc.getNumOperands(); in populateReads()
453 ID.Reads.resize(TotalUses); in populateReads()
463 ReadDescriptor &Read = ID.Reads[CurrentUse]; in populateReads()
475 ReadDescriptor &Read = ID.Reads[CurrentUse + I]; in populateReads()
496 ReadDescriptor &Read = ID.Reads[CurrentUse]; in populateReads()
505 ID.Reads.resize(CurrentUse); in populateReads()
526 Error InstrBuilder::verifyInstrDesc(const InstrDesc &ID, in verifyInstrDesc() argument
528 if (ID.NumMicroOps != 0) in verifyInstrDesc()
531 bool UsesBuffers = ID.UsedBuffers; in verifyInstrDesc()
532 bool UsesResources = !ID.Resources.empty(); in verifyInstrDesc()
547 while (SchedClassID && SM.getSchedClassDesc(SchedClassID)->isVariant()) in getVariantSchedClassID()
573 bool IsVariant = SM.getSchedClassDesc(SchedClassID)->isVariant(); in createInstrDescImpl()
598 std::unique_ptr<InstrDesc> ID = std::make_unique<InstrDesc>(); in createInstrDescImpl() local
599 ID->NumMicroOps = SCDesc.NumMicroOps; in createInstrDescImpl()
600 ID->SchedClassID = SchedClassID; in createInstrDescImpl()
617 initializeUsedResources(*ID, SCDesc, STI, ProcResourceMasks); in createInstrDescImpl()
618 computeMaxLatency(*ID, MCDesc, SCDesc, STI, CallLatency); in createInstrDescImpl()
623 populateWrites(*ID, MCI, SchedClassID); in createInstrDescImpl()
624 populateReads(*ID, MCI, SchedClassID); in createInstrDescImpl()
626 LLVM_DEBUG(dbgs() << "\t\tMaxLatency=" << ID->MaxLatency << '\n'); in createInstrDescImpl()
627 LLVM_DEBUG(dbgs() << "\t\tNumMicroOps=" << ID->NumMicroOps << '\n'); in createInstrDescImpl()
630 if (Error Err = verifyInstrDesc(*ID, MCI)) in createInstrDescImpl()
635 if ((ID->IsRecyclable = !IsVariadic && !IsVariant)) { in createInstrDescImpl()
637 Descriptors[DKey] = std::move(ID); in createInstrDescImpl()
645 VariantDescriptors[VDKey] = std::move(ID); in createInstrDescImpl()
693 NewIS->reset(); in createInstruction()
706 NewIS->setMayLoad(MCDesc.mayLoad()); in createInstruction()
707 NewIS->setMayStore(MCDesc.mayStore()); in createInstruction()
708 NewIS->setHasSideEffects(MCDesc.hasUnmodeledSideEffects()); in createInstruction()
709 NewIS->setBeginGroup(SCDesc.BeginGroup); in createInstruction()
710 NewIS->setEndGroup(SCDesc.EndGroup); in createInstruction()
711 NewIS->setRetireOOO(SCDesc.RetireOOO); in createInstruction()
720 IsZeroIdiom = MCIA->isZeroIdiom(MCI, Mask, ProcID); in createInstruction()
722 IsZeroIdiom || MCIA->isDependencyBreaking(MCI, Mask, ProcID); in createInstruction()
723 if (MCIA->isOptimizableRegisterMove(MCI, ProcID)) in createInstruction()
724 NewIS->setOptimizableMove(); in createInstruction()
734 // Skip non-register operands. in createInstruction()
749 if (IsInstRecycled && Idx < NewIS->getUses().size()) { in createInstruction()
750 NewIS->getUses()[Idx] = ReadState(RD, RegID); in createInstruction()
751 RS = &NewIS->getUses()[Idx++]; in createInstruction()
753 NewIS->getUses().emplace_back(RD, RegID); in createInstruction()
754 RS = &NewIS->getUses().back(); in createInstruction()
763 RS->setIndependentFromDef(); in createInstruction()
773 RS->setIndependentFromDef(); in createInstruction()
778 if (IsInstRecycled && Idx < NewIS->getUses().size()) in createInstruction()
779 NewIS->getUses().pop_back_n(NewIS->getUses().size() - Idx); in createInstruction()
790 // underlying super-registers using an APInt. in createInstruction()
794 // register writes implicitly clear the upper portion of a super-register. in createInstruction()
796 MCIA->clearsSuperRegisters(MRI, MCI, WriteMask); in createInstruction()
811 assert(RegID && "Expected a valid register ID!"); in createInstruction()
812 if (IsInstRecycled && Idx < NewIS->getDefs().size()) { in createInstruction()
813 NewIS->getDefs()[Idx++] = in createInstruction()
818 NewIS->getDefs().emplace_back(WD, RegID, in createInstruction()
825 if (IsInstRecycled && Idx < NewIS->getDefs().size()) in createInstruction()
826 NewIS->getDefs().pop_back_n(NewIS->getDefs().size() - Idx); in createInstruction()