while (SM.hasNext()) {
InstRef IR = SM.peekNext();
std::unique_ptr<Instruction> 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))
this, MRI, Subtarget.getSchedModel().MicroOpBufferSize,
RegisterFileSize, MaxRetirePerCycle, DispatchWidth, HWS.get())),
SM(Source), Cycles(0) {
- IB = llvm::make_unique<InstrBuilder>(MCII, HWS->getProcResourceMasks());
+ IB = llvm::make_unique<InstrBuilder>(Subtarget, MCII);
HWS->setDispatchUnit(DU.get());
}
llvm-mca.cpp
ResourcePressureView.cpp
Scheduler.cpp
- TimelineView.cpp
+ Support.cpp
SummaryView.cpp
+ TimelineView.cpp
View.cpp
)
}
}
-void InstrBuilder::createInstrDescImpl(const MCSubtargetInfo &STI,
- const MCInst &MCI) {
+void InstrBuilder::createInstrDescImpl(const MCInst &MCI) {
assert(STI.getSchedModel().hasInstrSchedModel() &&
"Itineraries are not yet supported!");
Descriptors[Opcode] = std::unique_ptr<const InstrDesc>(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.
assert(RegID > 0 && "Invalid register ID found!");
ReadState *NewRDS = new ReadState(RD, RegID);
NewIS->getUses().emplace_back(std::unique_ptr<ReadState>(NewRDS));
- }
+ }
// Now populate writes.
for (const WriteDescriptor &WD : D.Writes) {
#define LLVM_TOOLS_LLVM_MCA_INSTRBUILDER_H
#include "Instruction.h"
+#include "Support.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
/// 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<uint64_t> ProcResourceMasks;
+ llvm::SmallVector<uint64_t, 8> ProcResourceMasks;
llvm::DenseMap<unsigned short, std::unique_ptr<const InstrDesc>> Descriptors;
llvm::DenseMap<unsigned, std::unique_ptr<Instruction>> 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<uint64_t> 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
//
//===----------------------------------------------------------------------===//
-#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"
}
#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.
Resources[Mask] = llvm::make_unique<ResourceState>(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.
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
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);
}
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.
}
}
- const llvm::ArrayRef<uint64_t> getProcResMasks() const {
- return ProcResID2Mask;
- }
-
#ifndef NDEBUG
void dump() const {
for (const std::pair<uint64_t, UniqueResourceState> &Resource : Resources)
Resources->getBuffersUsage(Usage);
}
- const llvm::ArrayRef<uint64_t> getProcResourceMasks() const {
- return Resources->getProcResMasks();
- }
-
#ifndef NDEBUG
void dump() const;
#endif
--- /dev/null
+//===--------------------- 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<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++;
+ }
+}
+} // namespace mca
--- /dev/null
+//===--------------------- 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<uint64_t> &Masks);
+} // namespace mca
+
+#endif