From: Andrea Di Biagio Date: Tue, 20 Mar 2018 12:25:54 +0000 (+0000) Subject: [llvm-mca] Move the routine that computes processor resource masks to its own file. X-Git-Tag: llvmorg-7.0.0-rc1~10172 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=4704f0386bb8a29edb5d014ef7c00ef1b82fe78d;p=platform%2Fupstream%2Fllvm.git [llvm-mca] Move the routine that computes processor resource masks to its own file. Function computeProcResourceMasks is used by the ResourceManager (owned by the Scheduler) to compute resource masks for processor resources. Before this refactoring, there was an implicit dependency between the Scheduler and the InstrBuilder. That is because InstrBuilder has to know about resource masks when computing the set of processor resources consumed by a new instruction. With this patch, the functionality that computes resource masks has been extracted from the ResourceManager, and moved to a separate file (Support.h). This helps removing the dependency between the Scheduler and the InstrBuilder. No functional change intended. llvm-svn: 327973 --- diff --git a/llvm/tools/llvm-mca/Backend.cpp b/llvm/tools/llvm-mca/Backend.cpp index a45fd34..8d34175 100644 --- a/llvm/tools/llvm-mca/Backend.cpp +++ b/llvm/tools/llvm-mca/Backend.cpp @@ -34,7 +34,7 @@ void Backend::runCycle(unsigned Cycle) { while (SM.hasNext()) { InstRef IR = SM.peekNext(); std::unique_ptr NewIS( - IB->createInstruction(STI, IR.first, *IR.second)); + IB->createInstruction(IR.first, *IR.second)); const InstrDesc &Desc = NewIS->getDesc(); if (!DU->isAvailable(Desc.NumMicroOps) || !DU->canDispatch(IR.first, *NewIS)) diff --git a/llvm/tools/llvm-mca/Backend.h b/llvm/tools/llvm-mca/Backend.h index f8b6571..e9cf529 100644 --- a/llvm/tools/llvm-mca/Backend.h +++ b/llvm/tools/llvm-mca/Backend.h @@ -72,7 +72,7 @@ public: this, MRI, Subtarget.getSchedModel().MicroOpBufferSize, RegisterFileSize, MaxRetirePerCycle, DispatchWidth, HWS.get())), SM(Source), Cycles(0) { - IB = llvm::make_unique(MCII, HWS->getProcResourceMasks()); + IB = llvm::make_unique(Subtarget, MCII); HWS->setDispatchUnit(DU.get()); } diff --git a/llvm/tools/llvm-mca/CMakeLists.txt b/llvm/tools/llvm-mca/CMakeLists.txt index 126c75e..99db82b 100644 --- a/llvm/tools/llvm-mca/CMakeLists.txt +++ b/llvm/tools/llvm-mca/CMakeLists.txt @@ -21,7 +21,8 @@ add_llvm_tool(llvm-mca llvm-mca.cpp ResourcePressureView.cpp Scheduler.cpp - TimelineView.cpp + Support.cpp SummaryView.cpp + TimelineView.cpp View.cpp ) diff --git a/llvm/tools/llvm-mca/InstrBuilder.cpp b/llvm/tools/llvm-mca/InstrBuilder.cpp index 8a0335c..1bf2b36 100644 --- a/llvm/tools/llvm-mca/InstrBuilder.cpp +++ b/llvm/tools/llvm-mca/InstrBuilder.cpp @@ -357,8 +357,7 @@ static void populateReads(InstrDesc &ID, const MCInst &MCI, } } -void InstrBuilder::createInstrDescImpl(const MCSubtargetInfo &STI, - const MCInst &MCI) { +void InstrBuilder::createInstrDescImpl(const MCInst &MCI) { assert(STI.getSchedModel().hasInstrSchedModel() && "Itineraries are not yet supported!"); @@ -410,17 +409,15 @@ void InstrBuilder::createInstrDescImpl(const MCSubtargetInfo &STI, Descriptors[Opcode] = std::unique_ptr(ID); } -const InstrDesc &InstrBuilder::getOrCreateInstrDesc(const MCSubtargetInfo &STI, - const MCInst &MCI) { +const InstrDesc &InstrBuilder::getOrCreateInstrDesc(const MCInst &MCI) { auto it = Descriptors.find(MCI.getOpcode()); if (it == Descriptors.end()) - createInstrDescImpl(STI, MCI); + createInstrDescImpl(MCI); return *Descriptors[MCI.getOpcode()].get(); } -Instruction *InstrBuilder::createInstruction(const MCSubtargetInfo &STI, - unsigned Idx, const MCInst &MCI) { - const InstrDesc &D = getOrCreateInstrDesc(STI, MCI); +Instruction *InstrBuilder::createInstruction(unsigned Idx, const MCInst &MCI) { + const InstrDesc &D = getOrCreateInstrDesc(MCI); Instruction *NewIS = new Instruction(D); // Populate Reads first. @@ -446,7 +443,7 @@ Instruction *InstrBuilder::createInstruction(const MCSubtargetInfo &STI, assert(RegID > 0 && "Invalid register ID found!"); ReadState *NewRDS = new ReadState(RD, RegID); NewIS->getUses().emplace_back(std::unique_ptr(NewRDS)); - } + } // Now populate writes. for (const WriteDescriptor &WD : D.Writes) { diff --git a/llvm/tools/llvm-mca/InstrBuilder.h b/llvm/tools/llvm-mca/InstrBuilder.h index 252b68ca..a26b846 100644 --- a/llvm/tools/llvm-mca/InstrBuilder.h +++ b/llvm/tools/llvm-mca/InstrBuilder.h @@ -16,6 +16,7 @@ #define LLVM_TOOLS_LLVM_MCA_INSTRBUILDER_H #include "Instruction.h" +#include "Support.h" #include "llvm/MC/MCInstrInfo.h" #include "llvm/MC/MCSubtargetInfo.h" @@ -34,28 +35,26 @@ class DispatchUnit; /// Information from the machine scheduling model is used to identify processor /// resources that are consumed by an instruction. class InstrBuilder { + const llvm::MCSubtargetInfo &STI; const llvm::MCInstrInfo &MCII; - const llvm::ArrayRef ProcResourceMasks; + llvm::SmallVector ProcResourceMasks; llvm::DenseMap> Descriptors; llvm::DenseMap> Instructions; - void createInstrDescImpl(const llvm::MCSubtargetInfo &STI, - const llvm::MCInst &MCI); + void createInstrDescImpl(const llvm::MCInst &MCI); public: - InstrBuilder(const llvm::MCInstrInfo &mcii, - const llvm::ArrayRef Masks) - : MCII(mcii), ProcResourceMasks(Masks) {} + InstrBuilder(const llvm::MCSubtargetInfo &sti, const llvm::MCInstrInfo &mcii) + : STI(sti), MCII(mcii), + ProcResourceMasks(STI.getSchedModel().getNumProcResourceKinds()) { + computeProcResourceMasks(STI.getSchedModel(), ProcResourceMasks); + } - const InstrDesc &getOrCreateInstrDesc(const llvm::MCSubtargetInfo &STI, - const llvm::MCInst &MCI); + const InstrDesc &getOrCreateInstrDesc(const llvm::MCInst &MCI); - Instruction *createInstruction(const llvm::MCSubtargetInfo &STI, - unsigned Idx, - const llvm::MCInst &MCI); + Instruction *createInstruction(unsigned Idx, const llvm::MCInst &MCI); }; - } // namespace mca #endif diff --git a/llvm/tools/llvm-mca/Scheduler.cpp b/llvm/tools/llvm-mca/Scheduler.cpp index 0a8c736..4d7f1a2 100644 --- a/llvm/tools/llvm-mca/Scheduler.cpp +++ b/llvm/tools/llvm-mca/Scheduler.cpp @@ -11,9 +11,10 @@ // //===----------------------------------------------------------------------===// -#include "Scheduler.h" #include "Backend.h" #include "HWEventListener.h" +#include "Scheduler.h" +#include "Support.h" #include "llvm/Support/Debug.h" #include "llvm/Support/raw_ostream.h" @@ -43,6 +44,12 @@ void ResourceState::dump() const { } #endif +void ResourceManager::initialize(const llvm::MCSchedModel &SM) { + computeProcResourceMasks(SM, ProcResID2Mask); + for (unsigned I = 0, E = SM.getNumProcResourceKinds(); I < E; ++I) + addResource(*SM.getProcResource(I), I, ProcResID2Mask[I]); +} + // Adds a new resource state in Resources, as well as a new descriptor in // ResourceDescriptor. Map 'Resources' allows to quickly obtain ResourceState // objects from resource mask identifiers. @@ -52,36 +59,6 @@ void ResourceManager::addResource(const MCProcResourceDesc &Desc, Resources[Mask] = llvm::make_unique(Desc, Index, Mask); } -// Populate vector ProcResID2Mask with resource masks. One per each processor -// resource declared by the scheduling model. -void ResourceManager::computeProcResourceMasks(const MCSchedModel &SM) { - unsigned ProcResourceID = 0; - - // Create a unique bitmask for every processor resource unit. - // Skip resource at index 0, since it always references 'InvalidUnit'. - ProcResID2Mask.resize(SM.getNumProcResourceKinds()); - for (unsigned I = 1, E = SM.getNumProcResourceKinds(); I < E; ++I) { - const MCProcResourceDesc &Desc = *SM.getProcResource(I); - if (Desc.SubUnitsIdxBegin) - continue; - ProcResID2Mask[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; - ProcResID2Mask[I] |= 1ULL << ProcResourceID; - for (unsigned U = 0; U < Desc.NumUnits; ++U) { - uint64_t OtherMask = ProcResID2Mask[Desc.SubUnitsIdxBegin[U]]; - ProcResID2Mask[I] |= OtherMask; - } - ProcResourceID++; - } -} - // Returns the actual resource consumed by this Use. // First, is the primary resource ID. // Second, is the specific sub-resource ID. diff --git a/llvm/tools/llvm-mca/Scheduler.h b/llvm/tools/llvm-mca/Scheduler.h index 912658f..c74d3f1 100644 --- a/llvm/tools/llvm-mca/Scheduler.h +++ b/llvm/tools/llvm-mca/Scheduler.h @@ -60,22 +60,8 @@ enum ResourceStateEvent { class ResourceState { // Index to the MCProcResourceDesc in the processor Model. unsigned ProcResourceDescIndex; - // A resource unique identifier generated by the tool. - // For processor resource groups, the number of number of bits set in this - // mask is equivalent to the cardinality of the group plus one. - // Excluding the most significant bit, the remaining bits in the resource mask - // identify resources that are part of the group. - // - // Example, lets assume that this ResourceState describes a - // group containing ResourceA and ResourceB: - // - // ResourceA -- Mask: 0b001 - // ResourceB -- Mask: 0b010 - // ResourceAB -- Mask: 0b100 U (ResourceA::Mask | ResourceB::Mask) == 0b111 - // - // There is only one bit set for non-group resources. - // A ResourceMask can be used to solve set membership problems with simple bit - // manipulation operations. + // A resource mask. This is generated by the tool with the help of + // function `mca::createProcResourceMasks' (see Support.h). uint64_t ResourceMask; // A ProcResource can specify a number of units. For the purpose of dynamic @@ -309,16 +295,8 @@ class ResourceManager { void addResource(const llvm::MCProcResourceDesc &Desc, unsigned Index, uint64_t Mask); - // Compute processor resource masks for each processor resource declared by - // the scheduling model. - void computeProcResourceMasks(const llvm::MCSchedModel &SM); - // Populate resource descriptors. - void initialize(const llvm::MCSchedModel &SM) { - computeProcResourceMasks(SM); - for (unsigned I = 0, E = SM.getNumProcResourceKinds(); I < E; ++I) - addResource(*SM.getProcResource(I), I, ProcResID2Mask[I]); - } + void initialize(const llvm::MCSchedModel &SM); // Returns the actual resource unit that will be used. ResourceRef selectPipe(uint64_t ResourceID); @@ -354,7 +332,10 @@ class ResourceManager { } public: - ResourceManager(const llvm::MCSchedModel &SM) { initialize(SM); } + ResourceManager(const llvm::MCSchedModel &SM) + : ProcResID2Mask(SM.getNumProcResourceKinds()) { + initialize(SM); + } // Returns RS_BUFFER_AVAILABLE if buffered resources are not reserved, and if // there are enough available slots in the buffers. @@ -400,10 +381,6 @@ public: } } - const llvm::ArrayRef getProcResMasks() const { - return ProcResID2Mask; - } - #ifndef NDEBUG void dump() const { for (const std::pair &Resource : Resources) @@ -525,10 +502,6 @@ public: Resources->getBuffersUsage(Usage); } - const llvm::ArrayRef getProcResourceMasks() const { - return Resources->getProcResMasks(); - } - #ifndef NDEBUG void dump() const; #endif diff --git a/llvm/tools/llvm-mca/Support.cpp b/llvm/tools/llvm-mca/Support.cpp new file mode 100644 index 0000000..a0e0f59 --- /dev/null +++ b/llvm/tools/llvm-mca/Support.cpp @@ -0,0 +1,52 @@ +//===--------------------- Support.cpp ----------------------------*- C++ +//-*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// +/// This file implements a few helper functions used by various backend +/// components. +/// +//===----------------------------------------------------------------------===// + +#include "Support.h" +#include "llvm/MC/MCSchedule.h" + +namespace mca { + +using namespace llvm; + +void computeProcResourceMasks(const MCSchedModel &SM, + SmallVectorImpl &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++; + } +} +} // namespace mca diff --git a/llvm/tools/llvm-mca/Support.h b/llvm/tools/llvm-mca/Support.h new file mode 100644 index 0000000..a29ef8b --- /dev/null +++ b/llvm/tools/llvm-mca/Support.h @@ -0,0 +1,49 @@ +//===--------------------- Support.h ----------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// \file +/// +/// Helper functions used by various backend components. +/// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_TOOLS_LLVM_MCA_SUPPORT_H +#define LLVM_TOOLS_LLVM_MCA_SUPPORT_H + +#include "llvm/ADT/SmallVector.h" +#include "llvm/MC/MCSchedule.h" + +namespace mca { + +/// Populates vector Masks with processor resource masks. +/// +/// The number of bits set in a mask depends on the processor resource type. +/// Each processor resource mask has at least one bit set. For groups, the +/// number of bits set in the mask is equal to the cardinality of the group plus +/// one. Excluding the most significant bit, the remaining bits in the mask +/// identify processor resources that are part of the group. +/// +/// Example: +/// +/// ResourceA -- Mask: 0b001 +/// ResourceB -- Mask: 0b010 +/// ResourceAB -- Mask: 0b100 U (ResourceA::Mask | ResourceB::Mask) == 0b111 +/// +/// ResourceAB is a processor resource group containing ResourceA and ResourceB. +/// Each resource mask uniquely identifies a resource; both ResourceA and +/// ResourceB only have one bit set. +/// ResourceAB is a group; excluding the most significant bit in the mask, the +/// remaining bits identify the composition of the group. +/// +/// Resource masks are used by the ResourceManager to solve set membership +/// problems with simple bit manipulation operations. +void computeProcResourceMasks(const llvm::MCSchedModel &SM, + llvm::SmallVectorImpl &Masks); +} // namespace mca + +#endif