forked from OSchip/llvm-project
[llvm-mca] Remove namespace prefixes made redundant by r345612. NFC
llvm-svn: 345730
This commit is contained in:
parent
8e422d6775
commit
52578ac67c
|
@ -43,13 +43,12 @@ struct PipelineOptions {
|
|||
};
|
||||
|
||||
class Context {
|
||||
llvm::SmallVector<std::unique_ptr<HardwareUnit>, 4> Hardware;
|
||||
const llvm::MCRegisterInfo &MRI;
|
||||
const llvm::MCSubtargetInfo &STI;
|
||||
SmallVector<std::unique_ptr<HardwareUnit>, 4> Hardware;
|
||||
const MCRegisterInfo &MRI;
|
||||
const MCSubtargetInfo &STI;
|
||||
|
||||
public:
|
||||
Context(const llvm::MCRegisterInfo &R, const llvm::MCSubtargetInfo &S)
|
||||
: MRI(R), STI(S) {}
|
||||
Context(const MCRegisterInfo &R, const MCSubtargetInfo &S) : MRI(R), STI(S) {}
|
||||
Context(const Context &C) = delete;
|
||||
Context &operator=(const Context &C) = delete;
|
||||
|
||||
|
|
|
@ -62,23 +62,22 @@ public:
|
|||
class HWInstructionIssuedEvent : public HWInstructionEvent {
|
||||
public:
|
||||
using ResourceRef = std::pair<uint64_t, uint64_t>;
|
||||
HWInstructionIssuedEvent(
|
||||
const InstRef &IR,
|
||||
llvm::ArrayRef<std::pair<ResourceRef, ResourceCycles>> UR)
|
||||
HWInstructionIssuedEvent(const InstRef &IR,
|
||||
ArrayRef<std::pair<ResourceRef, ResourceCycles>> UR)
|
||||
: HWInstructionEvent(HWInstructionEvent::Issued, IR), UsedResources(UR) {}
|
||||
|
||||
llvm::ArrayRef<std::pair<ResourceRef, ResourceCycles>> UsedResources;
|
||||
ArrayRef<std::pair<ResourceRef, ResourceCycles>> UsedResources;
|
||||
};
|
||||
|
||||
class HWInstructionDispatchedEvent : public HWInstructionEvent {
|
||||
public:
|
||||
HWInstructionDispatchedEvent(const InstRef &IR, llvm::ArrayRef<unsigned> Regs,
|
||||
HWInstructionDispatchedEvent(const InstRef &IR, ArrayRef<unsigned> Regs,
|
||||
unsigned UOps)
|
||||
: HWInstructionEvent(HWInstructionEvent::Dispatched, IR),
|
||||
UsedPhysRegs(Regs), MicroOpcodes(UOps) {}
|
||||
// Number of physical register allocated for this instruction. There is one
|
||||
// entry per register file.
|
||||
llvm::ArrayRef<unsigned> UsedPhysRegs;
|
||||
ArrayRef<unsigned> UsedPhysRegs;
|
||||
// Number of micro opcodes dispatched.
|
||||
// This field is often set to the total number of micro-opcodes specified by
|
||||
// the instruction descriptor of IR.
|
||||
|
@ -93,12 +92,12 @@ public:
|
|||
|
||||
class HWInstructionRetiredEvent : public HWInstructionEvent {
|
||||
public:
|
||||
HWInstructionRetiredEvent(const InstRef &IR, llvm::ArrayRef<unsigned> Regs)
|
||||
HWInstructionRetiredEvent(const InstRef &IR, ArrayRef<unsigned> Regs)
|
||||
: HWInstructionEvent(HWInstructionEvent::Retired, IR),
|
||||
FreedPhysRegs(Regs) {}
|
||||
// Number of register writes that have been architecturally committed. There
|
||||
// is one entry per register file.
|
||||
llvm::ArrayRef<unsigned> FreedPhysRegs;
|
||||
ArrayRef<unsigned> FreedPhysRegs;
|
||||
};
|
||||
|
||||
// A HWStallEvent represents a pipeline stall caused by the lack of hardware
|
||||
|
@ -142,9 +141,9 @@ public:
|
|||
// Events generated by the Scheduler when buffered resources are
|
||||
// consumed/freed for an instruction.
|
||||
virtual void onReservedBuffers(const InstRef &Inst,
|
||||
llvm::ArrayRef<unsigned> Buffers) {}
|
||||
ArrayRef<unsigned> Buffers) {}
|
||||
virtual void onReleasedBuffers(const InstRef &Inst,
|
||||
llvm::ArrayRef<unsigned> Buffers) {}
|
||||
ArrayRef<unsigned> Buffers) {}
|
||||
|
||||
virtual ~HWEventListener() {}
|
||||
|
||||
|
|
|
@ -129,11 +129,7 @@ public:
|
|||
void dump() const;
|
||||
#endif
|
||||
|
||||
enum Status {
|
||||
LSU_AVAILABLE = 0,
|
||||
LSU_LQUEUE_FULL,
|
||||
LSU_SQUEUE_FULL
|
||||
};
|
||||
enum Status { LSU_AVAILABLE = 0, LSU_LQUEUE_FULL, LSU_SQUEUE_FULL };
|
||||
|
||||
// Returns LSU_AVAILABLE if there are enough load/store queue entries to serve
|
||||
// IR. It also returns LSU_AVAILABLE if IR is not a memory operation.
|
||||
|
|
|
@ -34,7 +34,7 @@ class WriteRef;
|
|||
/// Manages hardware register files, and tracks register definitions for
|
||||
/// register renaming purposes.
|
||||
class RegisterFile : public HardwareUnit {
|
||||
const llvm::MCRegisterInfo &MRI;
|
||||
const MCRegisterInfo &MRI;
|
||||
|
||||
// class RegisterMappingTracker is a physical register file (PRF) descriptor.
|
||||
// There is one RegisterMappingTracker for every PRF definition in the
|
||||
|
@ -85,7 +85,7 @@ class RegisterFile : public HardwareUnit {
|
|||
//
|
||||
// Users can limit the number of physical registers that are available in
|
||||
// regsiter file #0 specifying command line flag `-register-file-size=<uint>`.
|
||||
llvm::SmallVector<RegisterMappingTracker, 4> RegisterFiles;
|
||||
SmallVector<RegisterMappingTracker, 4> RegisterFiles;
|
||||
|
||||
// This type is used to propagate information about the owner of a register,
|
||||
// and the cost of allocating it in the PRF. Register cost is defined as the
|
||||
|
@ -101,7 +101,7 @@ class RegisterFile : public HardwareUnit {
|
|||
//
|
||||
// There is a RegisterRenamingInfo object for every logical register defined
|
||||
// by the target. RegisteRenamingInfo objects are stored into vector
|
||||
// `RegisterMappings`, and llvm::MCPhysReg IDs can be used to reference
|
||||
// `RegisterMappings`, and MCPhysReg IDs can be used to reference
|
||||
// elements in that vector.
|
||||
//
|
||||
// Each RegisterRenamingInfo is owned by a PRF, and field `IndexPlusCost`
|
||||
|
@ -117,8 +117,8 @@ class RegisterFile : public HardwareUnit {
|
|||
// register definition.
|
||||
struct RegisterRenamingInfo {
|
||||
IndexPlusCostPairTy IndexPlusCost;
|
||||
llvm::MCPhysReg RenameAs;
|
||||
llvm::MCPhysReg AliasRegID;
|
||||
MCPhysReg RenameAs;
|
||||
MCPhysReg AliasRegID;
|
||||
bool AllowMoveElimination;
|
||||
RegisterRenamingInfo()
|
||||
: IndexPlusCost(std::make_pair(0U, 1U)), RenameAs(0U), AliasRegID(0U),
|
||||
|
@ -144,7 +144,7 @@ class RegisterFile : public HardwareUnit {
|
|||
|
||||
// Used to track zero registers. There is one bit for each register defined by
|
||||
// the target. Bits are set for registers that are known to be zero.
|
||||
llvm::APInt ZeroRegisters;
|
||||
APInt ZeroRegisters;
|
||||
|
||||
// This method creates a new register file descriptor.
|
||||
// The new register file owns all of the registers declared by register
|
||||
|
@ -160,41 +160,40 @@ class RegisterFile : public HardwareUnit {
|
|||
// Here FPRegisterFile contains all the registers defined by register class
|
||||
// VR128RegClass and VR256RegClass. FPRegisterFile implements 60
|
||||
// registers which can be used for register renaming purpose.
|
||||
void addRegisterFile(const llvm::MCRegisterFileDesc &RF,
|
||||
llvm::ArrayRef<llvm::MCRegisterCostEntry> Entries);
|
||||
void addRegisterFile(const MCRegisterFileDesc &RF,
|
||||
ArrayRef<MCRegisterCostEntry> Entries);
|
||||
|
||||
// Consumes physical registers in each register file specified by the
|
||||
// `IndexPlusCostPairTy`. This method is called from `addRegisterMapping()`.
|
||||
void allocatePhysRegs(const RegisterRenamingInfo &Entry,
|
||||
llvm::MutableArrayRef<unsigned> UsedPhysRegs);
|
||||
MutableArrayRef<unsigned> UsedPhysRegs);
|
||||
|
||||
// Releases previously allocated physical registers from the register file(s).
|
||||
// This method is called from `invalidateRegisterMapping()`.
|
||||
void freePhysRegs(const RegisterRenamingInfo &Entry,
|
||||
llvm::MutableArrayRef<unsigned> FreedPhysRegs);
|
||||
MutableArrayRef<unsigned> FreedPhysRegs);
|
||||
|
||||
// Create an instance of RegisterMappingTracker for every register file
|
||||
// specified by the processor model.
|
||||
// If no register file is specified, then this method creates a default
|
||||
// register file with an unbounded number of physical registers.
|
||||
void initialize(const llvm::MCSchedModel &SM, unsigned NumRegs);
|
||||
void initialize(const MCSchedModel &SM, unsigned NumRegs);
|
||||
|
||||
public:
|
||||
RegisterFile(const llvm::MCSchedModel &SM, const llvm::MCRegisterInfo &mri,
|
||||
RegisterFile(const MCSchedModel &SM, const MCRegisterInfo &mri,
|
||||
unsigned NumRegs = 0);
|
||||
|
||||
// This method updates the register mappings inserting a new register
|
||||
// definition. This method is also responsible for updating the number of
|
||||
// allocated physical registers in each register file modified by the write.
|
||||
// No physical regiser is allocated if this write is from a zero-idiom.
|
||||
void addRegisterWrite(WriteRef Write,
|
||||
llvm::MutableArrayRef<unsigned> UsedPhysRegs);
|
||||
void addRegisterWrite(WriteRef Write, MutableArrayRef<unsigned> UsedPhysRegs);
|
||||
|
||||
// Removes write \param WS from the register mappings.
|
||||
// Physical registers may be released to reflect this update.
|
||||
// No registers are released if this write is from a zero-idiom.
|
||||
void removeRegisterWrite(const WriteState &WS,
|
||||
llvm::MutableArrayRef<unsigned> FreedPhysRegs);
|
||||
MutableArrayRef<unsigned> FreedPhysRegs);
|
||||
|
||||
// Returns true if a move from RS to WS can be eliminated.
|
||||
// On success, it updates WriteState by setting flag `WS.isEliminated`.
|
||||
|
@ -212,9 +211,8 @@ public:
|
|||
//
|
||||
// Current implementation can simulate up to 32 register files (including the
|
||||
// special register file at index #0).
|
||||
unsigned isAvailable(llvm::ArrayRef<unsigned> Regs) const;
|
||||
void collectWrites(llvm::SmallVectorImpl<WriteRef> &Writes,
|
||||
unsigned RegID) const;
|
||||
unsigned isAvailable(ArrayRef<unsigned> Regs) const;
|
||||
void collectWrites(SmallVectorImpl<WriteRef> &Writes, unsigned RegID) const;
|
||||
unsigned getNumRegisterFiles() const { return RegisterFiles.size(); }
|
||||
|
||||
// Notify each PRF that a new cycle just started.
|
||||
|
|
|
@ -189,8 +189,7 @@ class ResourceState {
|
|||
}
|
||||
|
||||
public:
|
||||
ResourceState(const llvm::MCProcResourceDesc &Desc, unsigned Index,
|
||||
uint64_t Mask);
|
||||
ResourceState(const MCProcResourceDesc &Desc, unsigned Index, uint64_t Mask);
|
||||
|
||||
unsigned getProcResourceID() const { return ProcResourceDescIndex; }
|
||||
uint64_t getResourceMask() const { return ResourceMask; }
|
||||
|
@ -211,9 +210,7 @@ public:
|
|||
/// `NumUnits` available units.
|
||||
bool isReady(unsigned NumUnits = 1) const;
|
||||
|
||||
bool isAResourceGroup() const {
|
||||
return llvm::countPopulation(ResourceMask) > 1;
|
||||
}
|
||||
bool isAResourceGroup() const { return countPopulation(ResourceMask) > 1; }
|
||||
|
||||
bool containsResource(uint64_t ID) const { return ResourceMask & ID; }
|
||||
|
||||
|
@ -228,7 +225,7 @@ public:
|
|||
}
|
||||
|
||||
unsigned getNumUnits() const {
|
||||
return isAResourceGroup() ? 1U : llvm::countPopulation(ResourceSizeMask);
|
||||
return isAResourceGroup() ? 1U : countPopulation(ResourceSizeMask);
|
||||
}
|
||||
|
||||
/// Checks if there is an available slot in the resource buffer.
|
||||
|
@ -286,10 +283,10 @@ class ResourceManager {
|
|||
|
||||
// Keeps track of which resources are busy, and how many cycles are left
|
||||
// before those become usable again.
|
||||
llvm::SmallDenseMap<ResourceRef, unsigned> BusyResources;
|
||||
SmallDenseMap<ResourceRef, unsigned> BusyResources;
|
||||
|
||||
// A table to map processor resource IDs to processor resource masks.
|
||||
llvm::SmallVector<uint64_t, 8> ProcResID2Mask;
|
||||
SmallVector<uint64_t, 8> ProcResID2Mask;
|
||||
|
||||
// Returns the actual resource unit that will be used.
|
||||
ResourceRef selectPipe(uint64_t ResourceID);
|
||||
|
@ -305,7 +302,7 @@ class ResourceManager {
|
|||
uint64_t ResourceMask);
|
||||
|
||||
public:
|
||||
ResourceManager(const llvm::MCSchedModel &SM);
|
||||
ResourceManager(const MCSchedModel &SM);
|
||||
virtual ~ResourceManager() = default;
|
||||
|
||||
// Overrides the selection strategy for the resource at index ResourceID in
|
||||
|
@ -319,17 +316,17 @@ public:
|
|||
|
||||
// Returns RS_BUFFER_AVAILABLE if buffered resources are not reserved, and if
|
||||
// there are enough available slots in the buffers.
|
||||
ResourceStateEvent canBeDispatched(llvm::ArrayRef<uint64_t> Buffers) const;
|
||||
ResourceStateEvent canBeDispatched(ArrayRef<uint64_t> Buffers) const;
|
||||
|
||||
// Return the processor resource identifier associated to this Mask.
|
||||
unsigned resolveResourceMask(uint64_t Mask) const;
|
||||
|
||||
// Consume a slot in every buffered resource from array 'Buffers'. Resource
|
||||
// units that are dispatch hazards (i.e. BufferSize=0) are marked as reserved.
|
||||
void reserveBuffers(llvm::ArrayRef<uint64_t> Buffers);
|
||||
void reserveBuffers(ArrayRef<uint64_t> Buffers);
|
||||
|
||||
// Release buffer entries previously allocated by method reserveBuffers.
|
||||
void releaseBuffers(llvm::ArrayRef<uint64_t> Buffers);
|
||||
void releaseBuffers(ArrayRef<uint64_t> Buffers);
|
||||
|
||||
// Reserve a processor resource. A reserved resource is not available for
|
||||
// instruction issue until it is released.
|
||||
|
@ -346,9 +343,9 @@ public:
|
|||
|
||||
void issueInstruction(
|
||||
const InstrDesc &Desc,
|
||||
llvm::SmallVectorImpl<std::pair<ResourceRef, ResourceCycles>> &Pipes);
|
||||
SmallVectorImpl<std::pair<ResourceRef, ResourceCycles>> &Pipes);
|
||||
|
||||
void cycleEvent(llvm::SmallVectorImpl<ResourceRef> &ResourcesFreed);
|
||||
void cycleEvent(SmallVectorImpl<ResourceRef> &ResourcesFreed);
|
||||
|
||||
#ifndef NDEBUG
|
||||
void dump() const {
|
||||
|
|
|
@ -63,7 +63,7 @@ private:
|
|||
std::vector<RUToken> Queue;
|
||||
|
||||
public:
|
||||
RetireControlUnit(const llvm::MCSchedModel &SM);
|
||||
RetireControlUnit(const MCSchedModel &SM);
|
||||
|
||||
bool isEmpty() const { return AvailableSlots == Queue.size(); }
|
||||
bool isAvailable(unsigned Quantity = 1) const {
|
||||
|
|
|
@ -105,25 +105,25 @@ class Scheduler : public HardwareUnit {
|
|||
/// Issue an instruction without updating the ready queue.
|
||||
void issueInstructionImpl(
|
||||
InstRef &IR,
|
||||
llvm::SmallVectorImpl<std::pair<ResourceRef, ResourceCycles>> &Pipes);
|
||||
SmallVectorImpl<std::pair<ResourceRef, ResourceCycles>> &Pipes);
|
||||
|
||||
// Identify instructions that have finished executing, and remove them from
|
||||
// the IssuedSet. References to executed instructions are added to input
|
||||
// vector 'Executed'.
|
||||
void updateIssuedSet(llvm::SmallVectorImpl<InstRef> &Executed);
|
||||
void updateIssuedSet(SmallVectorImpl<InstRef> &Executed);
|
||||
|
||||
// Try to promote instructions from WaitSet to ReadySet.
|
||||
// Add promoted instructions to the 'Ready' vector in input.
|
||||
void promoteToReadySet(llvm::SmallVectorImpl<InstRef> &Ready);
|
||||
void promoteToReadySet(SmallVectorImpl<InstRef> &Ready);
|
||||
|
||||
public:
|
||||
Scheduler(const llvm::MCSchedModel &Model, LSUnit *Lsu)
|
||||
: LSU(Lsu), Resources(llvm::make_unique<ResourceManager>(Model)) {
|
||||
Scheduler(const MCSchedModel &Model, LSUnit *Lsu)
|
||||
: LSU(Lsu), Resources(make_unique<ResourceManager>(Model)) {
|
||||
initializeStrategy(nullptr);
|
||||
}
|
||||
Scheduler(const llvm::MCSchedModel &Model, LSUnit *Lsu,
|
||||
Scheduler(const MCSchedModel &Model, LSUnit *Lsu,
|
||||
std::unique_ptr<SchedulerStrategy> SelectStrategy)
|
||||
: LSU(Lsu), Resources(llvm::make_unique<ResourceManager>(Model)) {
|
||||
: LSU(Lsu), Resources(make_unique<ResourceManager>(Model)) {
|
||||
initializeStrategy(std::move(SelectStrategy));
|
||||
}
|
||||
Scheduler(std::unique_ptr<ResourceManager> RM, LSUnit *Lsu,
|
||||
|
@ -168,8 +168,8 @@ public:
|
|||
/// result of this event.
|
||||
void issueInstruction(
|
||||
InstRef &IR,
|
||||
llvm::SmallVectorImpl<std::pair<ResourceRef, ResourceCycles>> &Used,
|
||||
llvm::SmallVectorImpl<InstRef> &Ready);
|
||||
SmallVectorImpl<std::pair<ResourceRef, ResourceCycles>> &Used,
|
||||
SmallVectorImpl<InstRef> &Ready);
|
||||
|
||||
/// Returns true if IR has to be issued immediately, or if IR is a zero
|
||||
/// latency instruction.
|
||||
|
@ -182,9 +182,9 @@ public:
|
|||
/// have changed in state, and that are now available to new instructions.
|
||||
/// Instructions executed are added to vector Executed, while vector Ready is
|
||||
/// populated with instructions that have become ready in this new cycle.
|
||||
void cycleEvent(llvm::SmallVectorImpl<ResourceRef> &Freed,
|
||||
llvm::SmallVectorImpl<InstRef> &Ready,
|
||||
llvm::SmallVectorImpl<InstRef> &Executed);
|
||||
void cycleEvent(SmallVectorImpl<ResourceRef> &Freed,
|
||||
SmallVectorImpl<InstRef> &Ready,
|
||||
SmallVectorImpl<InstRef> &Executed);
|
||||
|
||||
/// Convert a resource mask into a valid llvm processor resource identifier.
|
||||
unsigned getResourceID(uint64_t Mask) const {
|
||||
|
@ -203,9 +203,9 @@ public:
|
|||
// This routine performs a sanity check. This routine should only be called
|
||||
// when we know that 'IR' is not in the scheduler's instruction queues.
|
||||
void sanityCheck(const InstRef &IR) const {
|
||||
assert(llvm::find(WaitSet, IR) == WaitSet.end());
|
||||
assert(llvm::find(ReadySet, IR) == ReadySet.end());
|
||||
assert(llvm::find(IssuedSet, IR) == IssuedSet.end());
|
||||
assert(find(WaitSet, IR) == WaitSet.end() && "Already in the wait set!");
|
||||
assert(find(ReadySet, IR) == ReadySet.end() && "Already in the ready set!");
|
||||
assert(find(IssuedSet, IR) == IssuedSet.end() && "Already executing!");
|
||||
}
|
||||
#endif // !NDEBUG
|
||||
};
|
||||
|
|
|
@ -37,39 +37,32 @@ namespace mca {
|
|||
/// 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::MCRegisterInfo &MRI;
|
||||
const llvm::MCInstrAnalysis &MCIA;
|
||||
llvm::SmallVector<uint64_t, 8> ProcResourceMasks;
|
||||
const MCSubtargetInfo &STI;
|
||||
const MCInstrInfo &MCII;
|
||||
const MCRegisterInfo &MRI;
|
||||
const MCInstrAnalysis &MCIA;
|
||||
SmallVector<uint64_t, 8> ProcResourceMasks;
|
||||
|
||||
llvm::DenseMap<unsigned short, std::unique_ptr<const InstrDesc>> Descriptors;
|
||||
llvm::DenseMap<const llvm::MCInst *, std::unique_ptr<const InstrDesc>>
|
||||
VariantDescriptors;
|
||||
DenseMap<unsigned short, std::unique_ptr<const InstrDesc>> Descriptors;
|
||||
DenseMap<const MCInst *, std::unique_ptr<const InstrDesc>> VariantDescriptors;
|
||||
|
||||
llvm::Expected<const InstrDesc &>
|
||||
createInstrDescImpl(const llvm::MCInst &MCI);
|
||||
llvm::Expected<const InstrDesc &>
|
||||
getOrCreateInstrDesc(const llvm::MCInst &MCI);
|
||||
Expected<const InstrDesc &> createInstrDescImpl(const MCInst &MCI);
|
||||
Expected<const InstrDesc &> getOrCreateInstrDesc(const MCInst &MCI);
|
||||
|
||||
InstrBuilder(const InstrBuilder &) = delete;
|
||||
InstrBuilder &operator=(const InstrBuilder &) = delete;
|
||||
|
||||
llvm::Error populateWrites(InstrDesc &ID, const llvm::MCInst &MCI,
|
||||
unsigned SchedClassID);
|
||||
llvm::Error populateReads(InstrDesc &ID, const llvm::MCInst &MCI,
|
||||
unsigned SchedClassID);
|
||||
llvm::Error verifyInstrDesc(const InstrDesc &ID,
|
||||
const llvm::MCInst &MCI) const;
|
||||
Error populateWrites(InstrDesc &ID, const MCInst &MCI, unsigned SchedClassID);
|
||||
Error populateReads(InstrDesc &ID, const MCInst &MCI, unsigned SchedClassID);
|
||||
Error verifyInstrDesc(const InstrDesc &ID, const MCInst &MCI) const;
|
||||
|
||||
public:
|
||||
InstrBuilder(const llvm::MCSubtargetInfo &STI, const llvm::MCInstrInfo &MCII,
|
||||
const llvm::MCRegisterInfo &RI, const llvm::MCInstrAnalysis &IA);
|
||||
InstrBuilder(const MCSubtargetInfo &STI, const MCInstrInfo &MCII,
|
||||
const MCRegisterInfo &RI, const MCInstrAnalysis &IA);
|
||||
|
||||
void clear() { VariantDescriptors.shrink_and_clear(); }
|
||||
|
||||
llvm::Expected<std::unique_ptr<Instruction>>
|
||||
createInstruction(const llvm::MCInst &MCI);
|
||||
Expected<std::unique_ptr<Instruction>> createInstruction(const MCInst &MCI);
|
||||
};
|
||||
} // namespace mca
|
||||
} // namespace llvm
|
||||
|
|
|
@ -329,26 +329,26 @@ class InstructionBase {
|
|||
|
||||
// Output dependencies.
|
||||
// One entry per each implicit and explicit register definition.
|
||||
llvm::SmallVector<WriteState, 4> Defs;
|
||||
SmallVector<WriteState, 4> Defs;
|
||||
|
||||
// Input dependencies.
|
||||
// One entry per each implicit and explicit register use.
|
||||
llvm::SmallVector<ReadState, 4> Uses;
|
||||
SmallVector<ReadState, 4> Uses;
|
||||
|
||||
public:
|
||||
InstructionBase(const InstrDesc &D) : Desc(D), IsOptimizableMove(false) {}
|
||||
|
||||
llvm::SmallVectorImpl<WriteState> &getDefs() { return Defs; }
|
||||
const llvm::ArrayRef<WriteState> getDefs() const { return Defs; }
|
||||
llvm::SmallVectorImpl<ReadState> &getUses() { return Uses; }
|
||||
const llvm::ArrayRef<ReadState> getUses() const { return Uses; }
|
||||
SmallVectorImpl<WriteState> &getDefs() { return Defs; }
|
||||
const ArrayRef<WriteState> getDefs() const { return Defs; }
|
||||
SmallVectorImpl<ReadState> &getUses() { return Uses; }
|
||||
const ArrayRef<ReadState> getUses() const { return Uses; }
|
||||
const InstrDesc &getDesc() const { return Desc; }
|
||||
|
||||
unsigned getLatency() const { return Desc.MaxLatency; }
|
||||
|
||||
bool hasDependentUsers() const {
|
||||
return llvm::any_of(
|
||||
Defs, [](const WriteState &Def) { return Def.getNumUsers() > 0; });
|
||||
return any_of(Defs,
|
||||
[](const WriteState &Def) { return Def.getNumUsers() > 0; });
|
||||
}
|
||||
|
||||
unsigned getNumUsers() const {
|
||||
|
@ -420,8 +420,8 @@ public:
|
|||
|
||||
bool isEliminated() const {
|
||||
return isReady() && getDefs().size() &&
|
||||
llvm::all_of(getDefs(),
|
||||
[](const WriteState &W) { return W.isEliminated(); });
|
||||
all_of(getDefs(),
|
||||
[](const WriteState &W) { return W.isEliminated(); });
|
||||
}
|
||||
|
||||
// Forces a transition from state IS_AVAILABLE to state IS_EXECUTED.
|
||||
|
@ -458,12 +458,12 @@ public:
|
|||
void invalidate() { Data.second = nullptr; }
|
||||
|
||||
#ifndef NDEBUG
|
||||
void print(llvm::raw_ostream &OS) const { OS << getSourceIndex(); }
|
||||
void print(raw_ostream &OS) const { OS << getSourceIndex(); }
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifndef NDEBUG
|
||||
inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, const InstRef &IR) {
|
||||
inline raw_ostream &operator<<(raw_ostream &OS, const InstRef &IR) {
|
||||
IR.print(OS);
|
||||
return OS;
|
||||
}
|
||||
|
|
|
@ -55,11 +55,11 @@ class Pipeline {
|
|||
Pipeline &operator=(const Pipeline &P) = delete;
|
||||
|
||||
/// An ordered list of stages that define this instruction pipeline.
|
||||
llvm::SmallVector<std::unique_ptr<Stage>, 8> Stages;
|
||||
SmallVector<std::unique_ptr<Stage>, 8> Stages;
|
||||
std::set<HWEventListener *> Listeners;
|
||||
unsigned Cycles;
|
||||
|
||||
llvm::Error runCycle();
|
||||
Error runCycle();
|
||||
bool hasWorkToProcess();
|
||||
void notifyCycleBegin();
|
||||
void notifyCycleEnd();
|
||||
|
@ -67,7 +67,7 @@ class Pipeline {
|
|||
public:
|
||||
Pipeline() : Cycles(0) {}
|
||||
void appendStage(std::unique_ptr<Stage> S);
|
||||
llvm::Error run();
|
||||
Error run();
|
||||
void addEventListener(HWEventListener *Listener);
|
||||
};
|
||||
} // namespace mca
|
||||
|
|
|
@ -27,13 +27,13 @@ typedef std::pair<unsigned, const Instruction &> SourceRef;
|
|||
|
||||
class SourceMgr {
|
||||
using UniqueInst = std::unique_ptr<Instruction>;
|
||||
llvm::ArrayRef<UniqueInst> Sequence;
|
||||
ArrayRef<UniqueInst> Sequence;
|
||||
unsigned Current;
|
||||
const unsigned Iterations;
|
||||
static const unsigned DefaultIterations = 100;
|
||||
|
||||
public:
|
||||
SourceMgr(llvm::ArrayRef<UniqueInst> S, unsigned Iter)
|
||||
SourceMgr(ArrayRef<UniqueInst> S, unsigned Iter)
|
||||
: Sequence(S), Current(0), Iterations(Iter ? Iter : DefaultIterations) {}
|
||||
|
||||
unsigned getNumIterations() const { return Iterations; }
|
||||
|
@ -46,7 +46,7 @@ public:
|
|||
return SourceRef(Current, *Sequence[Current % Sequence.size()]);
|
||||
}
|
||||
|
||||
using const_iterator = llvm::ArrayRef<UniqueInst>::const_iterator;
|
||||
using const_iterator = ArrayRef<UniqueInst>::const_iterator;
|
||||
const_iterator begin() const { return Sequence.begin(); }
|
||||
const_iterator end() const { return Sequence.end(); }
|
||||
};
|
||||
|
|
|
@ -53,30 +53,29 @@ class DispatchStage final : public Stage {
|
|||
unsigned AvailableEntries;
|
||||
unsigned CarryOver;
|
||||
InstRef CarriedOver;
|
||||
const llvm::MCSubtargetInfo &STI;
|
||||
const MCSubtargetInfo &STI;
|
||||
RetireControlUnit &RCU;
|
||||
RegisterFile &PRF;
|
||||
|
||||
bool checkRCU(const InstRef &IR) const;
|
||||
bool checkPRF(const InstRef &IR) const;
|
||||
bool canDispatch(const InstRef &IR) const;
|
||||
llvm::Error dispatch(InstRef IR);
|
||||
Error dispatch(InstRef IR);
|
||||
|
||||
void updateRAWDependencies(ReadState &RS, const llvm::MCSubtargetInfo &STI);
|
||||
void updateRAWDependencies(ReadState &RS, const MCSubtargetInfo &STI);
|
||||
|
||||
void notifyInstructionDispatched(const InstRef &IR,
|
||||
llvm::ArrayRef<unsigned> UsedPhysRegs,
|
||||
ArrayRef<unsigned> UsedPhysRegs,
|
||||
unsigned uOps) const;
|
||||
|
||||
void collectWrites(llvm::SmallVectorImpl<WriteRef> &Vec,
|
||||
unsigned RegID) const {
|
||||
void collectWrites(SmallVectorImpl<WriteRef> &Vec, unsigned RegID) const {
|
||||
return PRF.collectWrites(Vec, RegID);
|
||||
}
|
||||
|
||||
public:
|
||||
DispatchStage(const llvm::MCSubtargetInfo &Subtarget,
|
||||
const llvm::MCRegisterInfo &MRI, unsigned MaxDispatchWidth,
|
||||
RetireControlUnit &R, RegisterFile &F)
|
||||
DispatchStage(const MCSubtargetInfo &Subtarget, const MCRegisterInfo &MRI,
|
||||
unsigned MaxDispatchWidth, RetireControlUnit &R,
|
||||
RegisterFile &F)
|
||||
: DispatchWidth(MaxDispatchWidth), AvailableEntries(MaxDispatchWidth),
|
||||
CarryOver(0U), CarriedOver(), STI(Subtarget), RCU(R), PRF(F) {}
|
||||
|
||||
|
@ -85,8 +84,8 @@ public:
|
|||
// The dispatch logic internally doesn't buffer instructions. So there is
|
||||
// never work to do at the beginning of every cycle.
|
||||
bool hasWorkToComplete() const override { return false; }
|
||||
llvm::Error cycleStart() override;
|
||||
llvm::Error execute(InstRef &IR) override;
|
||||
Error cycleStart() override;
|
||||
Error execute(InstRef &IR) override;
|
||||
|
||||
#ifndef NDEBUG
|
||||
void dump() const;
|
||||
|
|
|
@ -29,14 +29,14 @@ namespace mca {
|
|||
class ExecuteStage final : public Stage {
|
||||
Scheduler &HWS;
|
||||
|
||||
llvm::Error issueInstruction(InstRef &IR);
|
||||
Error issueInstruction(InstRef &IR);
|
||||
|
||||
// Called at the beginning of each cycle to issue already dispatched
|
||||
// instructions to the underlying pipelines.
|
||||
llvm::Error issueReadyInstructions();
|
||||
Error issueReadyInstructions();
|
||||
|
||||
// Used to notify instructions eliminated at register renaming stage.
|
||||
llvm::Error handleInstructionEliminated(InstRef &IR);
|
||||
Error handleInstructionEliminated(InstRef &IR);
|
||||
|
||||
ExecuteStage(const ExecuteStage &Other) = delete;
|
||||
ExecuteStage &operator=(const ExecuteStage &Other) = delete;
|
||||
|
@ -60,12 +60,12 @@ public:
|
|||
// state changes, and processor resources freed by the scheduler.
|
||||
// Instructions that transitioned to the 'Executed' state are automatically
|
||||
// moved to the next stage (i.e. RetireStage).
|
||||
llvm::Error cycleStart() override;
|
||||
llvm::Error execute(InstRef &IR) override;
|
||||
Error cycleStart() override;
|
||||
Error execute(InstRef &IR) override;
|
||||
|
||||
void notifyInstructionIssued(
|
||||
const InstRef &IR,
|
||||
llvm::ArrayRef<std::pair<ResourceRef, ResourceCycles>> Used) const;
|
||||
ArrayRef<std::pair<ResourceRef, ResourceCycles>> Used) const;
|
||||
void notifyInstructionExecuted(const InstRef &IR) const;
|
||||
void notifyInstructionReady(const InstRef &IR) const;
|
||||
void notifyResourceAvailable(const ResourceRef &RR) const;
|
||||
|
|
|
@ -40,9 +40,9 @@ public:
|
|||
|
||||
bool isAvailable(const InstRef &IR) const override;
|
||||
bool hasWorkToComplete() const override;
|
||||
llvm::Error execute(InstRef &IR) override;
|
||||
llvm::Error cycleStart() override;
|
||||
llvm::Error cycleEnd() override;
|
||||
Error execute(InstRef &IR) override;
|
||||
Error cycleStart() override;
|
||||
Error cycleEnd() override;
|
||||
};
|
||||
|
||||
} // namespace mca
|
||||
|
|
|
@ -27,17 +27,17 @@ namespace llvm {
|
|||
namespace mca {
|
||||
|
||||
class InstructionTables final : public Stage {
|
||||
const llvm::MCSchedModel &SM;
|
||||
llvm::SmallVector<std::pair<ResourceRef, ResourceCycles>, 4> UsedResources;
|
||||
llvm::SmallVector<uint64_t, 8> Masks;
|
||||
const MCSchedModel &SM;
|
||||
SmallVector<std::pair<ResourceRef, ResourceCycles>, 4> UsedResources;
|
||||
SmallVector<uint64_t, 8> Masks;
|
||||
|
||||
public:
|
||||
InstructionTables(const llvm::MCSchedModel &Model) : Stage(), SM(Model) {
|
||||
InstructionTables(const MCSchedModel &Model) : Stage(), SM(Model) {
|
||||
computeProcResourceMasks(Model, Masks);
|
||||
}
|
||||
|
||||
bool hasWorkToComplete() const override { return false; }
|
||||
llvm::Error execute(InstRef &IR) override;
|
||||
Error execute(InstRef &IR) override;
|
||||
};
|
||||
} // namespace mca
|
||||
} // namespace llvm
|
||||
|
|
|
@ -37,8 +37,8 @@ public:
|
|||
: Stage(), RCU(R), PRF(F) {}
|
||||
|
||||
bool hasWorkToComplete() const override { return !RCU.isEmpty(); }
|
||||
llvm::Error cycleStart() override;
|
||||
llvm::Error execute(InstRef &IR) override;
|
||||
Error cycleStart() override;
|
||||
Error execute(InstRef &IR) override;
|
||||
void notifyInstructionRetired(const InstRef &IR) const;
|
||||
};
|
||||
|
||||
|
|
|
@ -47,13 +47,13 @@ public:
|
|||
|
||||
/// Called once at the start of each cycle. This can be used as a setup
|
||||
/// phase to prepare for the executions during the cycle.
|
||||
virtual llvm::Error cycleStart() { return llvm::ErrorSuccess(); }
|
||||
virtual Error cycleStart() { return ErrorSuccess(); }
|
||||
|
||||
/// Called once at the end of each cycle.
|
||||
virtual llvm::Error cycleEnd() { return llvm::ErrorSuccess(); }
|
||||
virtual Error cycleEnd() { return ErrorSuccess(); }
|
||||
|
||||
/// The primary action that this stage performs on instruction IR.
|
||||
virtual llvm::Error execute(InstRef &IR) = 0;
|
||||
virtual Error execute(InstRef &IR) = 0;
|
||||
|
||||
void setNextInSequence(Stage *NextStage) {
|
||||
assert(!NextInSequence && "This stage already has a NextInSequence!");
|
||||
|
@ -68,7 +68,7 @@ public:
|
|||
///
|
||||
/// Stages are responsible for moving instructions to their immediate
|
||||
/// successor stages.
|
||||
llvm::Error moveToTheNextStage(InstRef &IR) {
|
||||
Error moveToTheNextStage(InstRef &IR) {
|
||||
assert(checkNextStage(IR) && "Next stage is not ready!");
|
||||
return NextInSequence->execute(IR);
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ namespace llvm {
|
|||
namespace mca {
|
||||
|
||||
template <typename T>
|
||||
class InstructionError : public llvm::ErrorInfo<InstructionError<T>> {
|
||||
class InstructionError : public ErrorInfo<InstructionError<T>> {
|
||||
public:
|
||||
static char ID;
|
||||
std::string Message;
|
||||
|
@ -33,10 +33,10 @@ public:
|
|||
InstructionError(std::string M, const T &MCI)
|
||||
: Message(std::move(M)), Inst(MCI) {}
|
||||
|
||||
void log(llvm::raw_ostream &OS) const override { OS << Message; }
|
||||
void log(raw_ostream &OS) const override { OS << Message; }
|
||||
|
||||
std::error_code convertToErrorCode() const override {
|
||||
return llvm::inconvertibleErrorCode();
|
||||
return inconvertibleErrorCode();
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -70,8 +70,7 @@ public:
|
|||
else {
|
||||
// Create a common denominator for LHS and RHS by calculating the least
|
||||
// common multiple from the GCD.
|
||||
unsigned GCD =
|
||||
llvm::GreatestCommonDivisor64(Denominator, RHS.Denominator);
|
||||
unsigned GCD = GreatestCommonDivisor64(Denominator, RHS.Denominator);
|
||||
unsigned LCM = (Denominator * RHS.Denominator) / GCD;
|
||||
unsigned LHSNumerator = Numerator * (LCM / Denominator);
|
||||
unsigned RHSNumerator = RHS.Numerator * (LCM / RHS.Denominator);
|
||||
|
@ -104,16 +103,16 @@ public:
|
|||
///
|
||||
/// 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);
|
||||
void computeProcResourceMasks(const MCSchedModel &SM,
|
||||
SmallVectorImpl<uint64_t> &Masks);
|
||||
|
||||
/// Compute the reciprocal block throughput from a set of processor resource
|
||||
/// cycles. The reciprocal block throughput is computed as the MAX between:
|
||||
/// - NumMicroOps / DispatchWidth
|
||||
/// - ProcResourceCycles / #ProcResourceUnits (for every consumed resource).
|
||||
double computeBlockRThroughput(const llvm::MCSchedModel &SM,
|
||||
unsigned DispatchWidth, unsigned NumMicroOps,
|
||||
llvm::ArrayRef<unsigned> ProcResourceUsage);
|
||||
double computeBlockRThroughput(const MCSchedModel &SM, unsigned DispatchWidth,
|
||||
unsigned NumMicroOps,
|
||||
ArrayRef<unsigned> ProcResourceUsage);
|
||||
} // namespace mca
|
||||
} // namespace llvm
|
||||
|
||||
|
|
Loading…
Reference in New Issue